Я получаю штраф за производительность при смешивании SSE целочисленных/плавающих SIMD-инструкций

Я использовал x86 SIMD-инструкции (SSE1234) в виде intrinsics довольно много в последнее время. То, что я нашел разочаровывающим, заключается в том, что SSE ISA имеет несколько простых инструкций, которые доступны только для float или только для целых чисел, но теоретически должны выполняться одинаково для обоих. Например, как float, так и double-векторы имеют инструкции для загрузки более 64 бит 128-битного вектора из адреса (movhps, movhpd), но нет такой инструкции для целых векторов.

Мой вопрос:

Есть ли какие-либо причины ожидать повышения производительности при использовании команд с плавающей запятой для целых векторов, например. используя movhps для загрузки данных в целочисленный вектор?

Я написал несколько тестов, чтобы проверить это, но я полагаю, что их результаты не заслуживают доверия. Очень сложно написать правильный тест, который исследует все угловые случаи для таких вещей, особенно когда планирование команд, скорее всего, задействовано здесь.

Связанный вопрос:

Другие тривиально похожие вещи также имеют несколько инструкций, которые в основном одинаковы. Например, я могу выполнять побитовое ИЛИ с помощью por, orps или orpd. Может ли кто-нибудь объяснить, в чем цель этих дополнительных инструкций? Я думаю, это может быть связано с различными алгоритмами планирования, применяемыми к каждой команде.

Ответы

Ответ 1

От эксперта (очевидно, не меня: P): http://www.agner.org/optimize/optimizing_assembly.pdf [13.2. Использование векторных инструкций с другими типами данных, чем они предназначены для (стр. 118-119)]:

Существует штраф за использование неправильных инструкций для некоторых процессоров. Это потому что процессор может иметь разные шины данных или разные исполнительные блоки для целочисленных и данные с плавающей запятой. Перемещение данных между целыми числами и единицами с плавающей запятой может один или несколько тактовых циклов в зависимости от процессора, как указано в таблице 13.2.

Processor                       Bypass delay, clock cycles 
  Intel Core 2 and earlier        1 
  Intel Nehalem                   2 
  Intel Sandy Bridge and later    0-1 
  Intel Atom                      0 
  AMD                             2 
  VIA Nano                        2-3 
Table 13.2. Data bypass delays between integer and floating point execution units