Можно ли смешивать устаревшие закодированные 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). Я нашел ту же самую проблему с файлом сборки.