Генерировать константы намного проще (и быстрее), если четыре константы с плавающей точкой одинаковы. Например, битовая комбинация для 1.f равна 0x3f800000. Один из способов это можно сделать с помощью SSE2
register __m128i onef;
__asm__ ( "pcmpeqb %0, %0" : "=x" ( onef ) );
onef = _mm_slli_epi32( onef, 25 );
onef = _mm_srli_epi32( onef, 2 );
Другой подход с SSE4.1:
register uint32_t t = 0x3f800000;
register __m128 onef;
__asm__ ( "pinsrd %0, %1, 0" : "=x" ( onef ) : "r" ( t ) );
onef = _mm_shuffle_epi32( onef, 0 );
Обратите внимание, что я не могу, если эта версия работает быстрее, чем SSE2, я ее не профилировал, только проверял, что результат был верным.
Если значения каждого из четырех чисел с плавающей точкой должны быть разными, то каждая из констант может быть сгенерирована и перемешана или смешана вместе.
Является ли это полезным или нет, зависит от вероятности пропуска кэша, иначе загрузка константы из памяти происходит быстрее. Подобные приемы очень полезны в vmx / altivec, но большие кэши на большинстве ПК могут сделать это менее полезным для sse.
Это хорошо обсуждается в Руководстве по оптимизации Agner Fog, книга 2, раздел 13.4, http://www.agner.org/optimize/.
Последнее замечание: использование встроенного ассемблера выше зависит от gcc, причина в том, чтобы разрешить использование неинициализированных переменных без генерации предупреждения компилятора. При использовании vc вам может понадобиться или не потребоваться сначала инициализировать переменные с помощью _mm_setzero_ps (), а затем надеяться, что оптимизатор может удалить это.