Многие инструкции SSE позволяют исходному операнду быть адресом с 16-байтовым выровненным адресом. Например, различные инструкции (un) pack. PUNCKLBW имеет следующую подпись:SSE2 intrinsics: непосредственно доступ к памяти
PUNPCKLBW XMM1, xmm2/M128
Теперь это не представляется возможным вообще с встроенными функциями. Похоже, что необходимо использовать _mm_load * intrinsics, чтобы читать что-либо в памяти. Это внутренняя для PUNPCKLBW:
__m128i _mm_unpacklo_epi8 (__m128i а, __m128i б);
(Насколько я знаю, тип __m128i всегда относится к регистру XMM.)
Теперь, почему это? Это довольно печально, так как я вижу некоторый потенциал оптимизации, обращаясь к памяти напрямую ...
Я бы не стал жаловаться, если компилятор оптимизировал его, но, по крайней мере, clang и gcc этого не делают. Это легко проверить с помощью опции -S. Я нахожу вербальные внутренние операции -> сборные переводы практически для любых внутренних и могут привязывать регистры непосредственно к переменным. Похоже, что эти компиляторы вряд ли оптимизируют код встроенного кода SIMD ... – dietr
@dietr: clang и gcc обе делают эту оптимизацию, как вы можете видеть в моем примере. Вы строите с отключенной оптимизацией? Попробуйте использовать '-O1' или выше. –
Я использую -O2. Я думаю, что gcc/clang просто не видит никакого потенциала оптимизации в моем конкретном фрагменте кода ... – dietr