Можно ли смешивать устаревшие закодированные SSE инструкции и кодированные VEX в одном и том же кодовом пути?
Наряду с внедрением AVX Intel представила схему кодирования VEX в архитектуру Intel 64 и IA-32. Эта схема кодирования используется в основном с инструкциями AVX. Мне было интересно, можно ли смешивать VEX-закодированные инструкции и теперь называемые "устаревшие SSE" инструкции.
Основная причина, по которой я задаю этот вопрос, - это размер кода. Рассмотрим эти две инструкции:
shufps xmm0, xmm0, 0
vshufps xmm0, xmm0, xmm0, 0
Я обычно использую первый, чтобы "транслировать" скалярное значение ко всем местам в регистре XMM. Теперь в наборе инструкций говорится, что единственная разница между этими двумя (в данном случае) состоит в том, что VEX-кодированный очищает более высокие ( >= 128) биты регистра YMM. Предположим, что мне это не нужно, какое преимущество использования версии VEX в этом случае? Первая команда принимает 4 байта (0FC6C000
), вторая - 5 (C5F8C6C000
).
Спасибо за все ответы заранее.
Ответы
Ответ 1
В текущих реализациях, если (по крайней мере), верхние половины были reset (VZEROUPPER или VZEROALL), нет штрафа за использование устаревших инструкций SSE.
Как подробно описано на стр. 128 в Agner Fog: оптимизация подпрограмм в сборке, используя устаревшие инструкции SSE, в то время как (некоторые) верхние половины используются штраф за исполнение. Это наказание возникает один раз при входе в состояние, в котором регистры YMM разделены посередине, и еще раз при выходе из этого состояния.
Смешивание 128-битных инструкций и устаревших инструкций SSE, закодированных в VEX, не является проблемой.
Ответ 2
Это не безопасно. В соответствии с руководство по разработке программного обеспечения Intel, версия VEX.128 имеет нулевую верхнюю половину регистра YMM, устаревшая версия SSE этого не делает. Хуже того: некоторые сборщики (например, gasm) могут преобразовывать SHUFPS в VSHUFPS при создании объектного файла (когда применяется флаг -mavx). Я нашел ту же самую проблему с файлом сборки.