Перевернутый знак на упакованных SSE-поплавках
Я ищу наиболее эффективный метод отображения знака на всех четырех поплавках, упакованных в регистр SSE.
Я не нашел неотъемлемого элемента для этого в руководстве по разработке программного обеспечения Intel Architecture. Ниже приведены те вещи, которые я уже пробовал.
Для каждого случая я зацикливал код на 10 миллиардов раз и получил обозначение стены. Я пытаюсь хотя бы совместить 4 секунды, это требует моего подхода, отличного от 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.
Ответы
Ответ 1
Просто, чтобы закончить собственный ответ по документации 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
будет делать в большинстве случаев.
Ответ 2
Этот союз не нужен, лучше всего в мире (читаемость, скорость и переносимость):
_mm_xor_ps(vec, _mm_set1_ps(-0.f))
Ответ 3
Урок жизни о кодировании до 3 утра утром.
Я никогда не пробовал просто использовать унарный минус на моем упакованном векторе. Это фактически компилируется и имеет ту же производительность, что и подход, отличный от SIMD.