Я ищу наиболее эффективный способ зеркального отражения знака на всех четырех плаваниях, упакованных в регистре SSE.
Я не нашел внутреннее для того, чтобы сделать это в программном обеспечении архитектуры Intel dev руководство. Ниже вещи, которые я уже попробовал.
Для каждого случая я циклично выполнился по коду 10 миллиардов раз и указал на разовое стеной. Я пытаюсь, по крайней мере, соответствовать 4 секундам, это проявляет мой non-SIMD подход, который использует просто оператор унарный минус.
[48 секунд]
_mm_sub_ps( _mm_setzero_ps(), vec );
[32 секунды]
_mm_mul_ps( _mm_set1_ps( -1.0f ), vec );
[9 секунд]
union NegativeMask { int intRep; float fltRep; } negMask; negMask.intRep = 0x80000000; _mm_xor_ps( _mm_set1_ps( negMask.fltRep ), vec );
Компилятор является gcc 4.2 с-O3. ЦП является Intel Core 2 Duo.
Просто чтобы дополнить свой ответ в документации gcc об этих встроенных векторах:
The types defined in this manner can be used with a subset of normal C
operations. Currently, GCC will allow using the following operators on
these types: `+, -, *, /, unary minus, ^, |, &, ~'.
Вероятно, будет хорошей идеей всегда придерживаться их, когда это возможно. С очень высокими шансами gcc всегда предоставит наиболее эффективный код для этого материала SSE.
Для параметров компилятора добавьте что-то более специфичное для вашей архитектуры, в большинстве случаев подойдет что-то вроде -march = native
.
Жизненный урок о кодировании до трех часов ночи.....
Я никогда не пробовал просто использовать унарный минус на моем упакованном векторе. Это действительно компилируется и имеет точно такую же производительность, как и не-SIMD подход.
Этот союз на самом деле не нужен, это лучшее из всех миров (читаемость, скорость и переносимость):
_mm_xor_ps(vec, _mm_set1_ps(-0.f))