Каковы лучшие последовательности команд для генерации векторных констант на лету?
«Наилучший» означает наименьшее количество инструкций (или наименьшее количество мопов, если какие-либо инструкции декодируются в более чем один моп). Размер машинного кода в байтах является прерывателем для равного количества insn.
Генерация констант по самой своей природе является началом новой цепочки зависимостей, поэтому латентность имеет значение. Также необычно генерировать константы внутри цикла, поэтому требования к пропускной способности и порту выполнения также в основном не имеют значения.
Генерация констант вместо их загрузки требует больше инструкций (за исключением всех нулей или всех единиц), поэтому она потребляет драгоценное пространство uop-cache. Это может быть даже более ограниченный ресурс, чем кэш данных.
Агнер Фог отличноОптимизация руководства по сборке охватывает это вSection 13.4
, Таблица 13.10 содержит последовательности для генерации векторов, где каждый элемент0
, 1
, 2
, 3
, 4
, -1
, или же-2
с размерами элементов от 8 до 64 бит. Таблица 13.11 содержит последовательности для генерации некоторых значений с плавающей запятой (0.0
, 0.5
, 1.0
, 1.5
, 2.0
, -2.0
и битовые маски для знака бит.)
Последовательности Agner Fog используют только SSE2, либо по замыслу, либо потому, что он некоторое время не обновлялся.
Какие еще константы можно сгенерировать с помощью коротких неочевидных последовательностей инструкций? (Дальнейшие расширения с различным числом сдвигов очевидны и не «интересны».) Есть ли лучшие последовательности для генерации констант, которые перечисляет Agner Fog?
Как переместить 128-битные немедленные в регистры XMM иллюстрирует некоторые способы помещения произвольной константы 128b в поток инструкций, но это обычно не имеет смысла (это не экономит место и занимает много места в uop-кэше).