TL:DR: Это синонимы; имя bslli
более новое, введенное примерно в то же время, что и новые встроенные функции AVX-512 (где-то до 2015 года, долго после того, как SSE2 _mm_slli_si128
стал широко использоваться). Я нахожу это более ясным и рекомендую его для новой разработки.
SSE/AVX2/AVX-512 не имеют битовых сдвигов с размерами элементов более 64. (Или любая другая операция битовой детализации, такая как add
, за исключением чисто вертикального побитового логического материала, который на самом деле 128 полностью отдельных операций, а не одна большая широкая , Или для целей маскировки AVX-512 и широковещательной загрузки, может быть в виде фрагментов dword или qword, таких как _mm512_xor_epi32
/ vpxord
а>)
Вы должны каким-то образом эмулировать это, что может быть довольно эффективным для подсчета констант времени компиляции, поэтому вы можете выбирать между стратегиями в соответствии с c >= 64
, с особыми случаями для c%8
, сводящимися к байтовому сдвигу. Существующие вопросы и ответы SO охватывают это или см. ответ @Soonts на этот вопрос.
Количество переменных времени выполнения было бы отстойным; вам придется разветвляться или делать оба пути и смешивать, в отличие от битовых сдвигов элементов, где _mm_sll_epi64(v, _mm_cvtsi32_si128(i))
может компилироваться в movd
/psllq xmm, xmm
. К сожалению, аппаратных версий инструкций байтового тасования/сдвига с переменным числом переменных не существует, только для версий с битовым сдвигом.
bslli
/ bsrli
— это новые, более четкие внутренние имена для тех же инструкций asm.
В b
имена поддерживаются в текущей версии всех 4 основных компиляторов для x86 (Godbolt ), и я бы порекомендовал их для новой разработки, если только вам не нужна обратная совместимость с корявыми старыми компиляторами или по какой-то причине вам нравится старое имя, которое не позволяет отличить его от других операций. (например, знакомство; если вы не хотите, чтобы людям приходилось искать это новомодное имя в руководстве.)
- gcc с 4.8
- лязг с 3.7
- ICC, начиная с ICC13 или ранее, у Godbolt нет более старых
- MSVC начиная с 19.14 или ранее, у Godbolt нет более старых
Если вы посмотрите руководство по внутренним компонентам, _mm_slli_si128
указан как встроенный параметр для PSLLDQ
, который представляет собой сдвиг байта. Это не ошибка, а просто шутка Intel или какой-то другой процесс, который они использовали для выбора имен для встроенных функций еще во времена SSE2. (В информатике есть только две сложные проблемы: инвалидация кеша и присвоение имен).
В мнемонике ассемблера также используется тот же шаблон, при котором перетасовка байтов не выглядит иначе, чем сдвиг битов. psllw xmm, 1
/ pslld
/ psllq
/ pslldq
. Опять же, вам просто нужно знать, что 128-битный размер особенный и должен быть перетасовкой байтов, а не битовым сдвигом, потому что в x86 такого нет. (Или вы должны проверить руководство.)
Запись руководства asm для pslldq
, в свою очередь, перечисляет встроенные функции для его форм, что интересно, только с использованием b
имя для версии __m512i
AVX-512BW. Когда SSE2 и AVX2 были новыми, я думаю, что _mm_slli_si128
и _mm256_slli_si256
были единственными доступными именами. Конечно, он более поздний, чем встроенные функции SSE2.
(Обратите внимание, что версии si256
и si512
— это всего лишь 2 или 4 копии 16-байтовой операции, не сдвигающие байты по 128-битным дорожкам; то, о чем просили несколько других вопросов и ответов. Это часто делает AVX2 подобные варианты перетасовок и palignr
намного менее полезны, чем они могли бы быть в противном случае: либо вообще не стоит использовать, либо нужны дополнительные перетасовки вдобавок к этому.)
Я думаю, что это новое имя bslli
было введено, когда AVX-512 был новым. Примерно в то же время Intel изобрела несколько новых имен для других встроенных функций, а встроенные функции загрузки/сохранения AVX-512 принимают void*
вместо __m512i*
, что является значительным улучшением количества шума в коде, особенно для C, где разрешено неявное преобразование в void*
. (Создание смещенного __m512i*
на самом деле не является проблемой. в терминах C, но вы не могли нормально разопределить его, поэтому это выглядит странно.) Так что тогда велась работа по очистке внутреннего именования, и я думаю, что это было частью этого.
(AVX-512 также дал Intel возможность ввести некоторые довольно плохие имена, такие как _mm_loadu_epi32(const void*)
— вы могли бы догадаться, что это строго безопасный способ выполнения 32-битной загрузки movd
, верно? Нет, к сожалению, это встроенный для vmovdqu32 xmm, [mem]
без маскировки. Это просто _mm_loadu_si128
с другим типом C для указателя arg. Это сделано для согласованности с шаблоном именования для _mm_maskz_loadu_epi32
. Было бы неплохо иметь встроенные функции void*
загрузки/сохранения для __m128i
и __m256i
, но если они вводят в заблуждение такие имена (особенно когда вы не используете версии mask
/maskz
в соседнем коде), я просто буду придерживаться этих громоздких приведений _mm256_loadu_si256( (const __m256i*)(arr + i) )
для старой встроенной функции, потому что я люблю набирать 256
три раза. ›.‹
Я бы хотел, чтобы asm был более удобным в сопровождении (или чтобы встроенные функции просто использовали мнемонику asm), потому что он намного более лаконичен; Intel, как правило, хорошо называет свои мнемоники.
Это несколько, но не полностью помогает отметить разницу между epi16/32/64
и si128
: EPI = расширенное (SSE вместо MMX) упакованное целое число. (Упакованный подразумевает несколько элементов SIMD). si128
означает целый 128-битный целочисленный вектор.
Из имени невозможно сделать вывод, что вы не делаете то же самое, просто делая одно 128-битное целое число вместо упакованных элементов. Вам просто нужно знать, что нет вещей с битовой гранулярностью, которые когда-либо пересекают 64-битные границы, только перетасовки SIMD (которые работают с байтами). Это позволяет избежать комбинаторного взрыва, связанного с созданием действительно широкого бочкообразного переключателя, или распространения переноса на такое большое расстояние для 128-битного сложения или чего-либо еще.
person
Peter Cordes
schedule
07.02.2021
(V)PSLLDQ
, выполняющая побайтовый сдвиг, сначала была раскрыта через встроенную функцию с непоследовательным названием (с использованием sli, ошибочно предполагающую сдвиг битов), в то время как встроенная функция с постоянным именем ( использование bslli, правильно предполагающее смещение байтов) не было добавлено намного позже, и в этот момент было невозможно удалить старую встроенную функцию, не нарушая существующий код. Таким образом, для нового кода предпочтительнее использовать вариант bslli в качестве встроенных функций с более подходящим названием. - person njuffa   schedule 07.02.2021