Подтвердить что ты не робот

Перевернутый знак на упакованных 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.

4b9b3361

Ответ 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.