Я получаю штраф за производительность при смешивании 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