Почему SSE set (_mm_set_ps) отменяет порядок аргументов

Недавно я заметил, что

_m128 m = _mm_set_ps(0,1,2,3);

помещает 4 поплавка в обратный порядок при переносе в массив с плавающей запятой:

(float*) p = (float*)(&m);
// p[0] == 3
// p[1] == 2
// p[2] == 1
// p[3] == 0

То же самое происходит и с union { _m128 m; float[4] a; }.

Почему SSE-операции используют этот порядок? Это неважно, но немного запутанно.

И следующий вопрос:

При обращении к элементам в массиве по индексу следует получить доступ в порядке 0..3 или в порядке 3..0?

Ответ 1

Это просто конвенция; они должны были выбрать какой-то порядок, и это действительно неважно, какой порядок до тех пор, пока все следуют за ним. Intel, похоже, малодушна.

Что касается доступа по индексу, то лучше всего попытаться избежать этого. Ничто не убивает векторную производительность, как элементарный доступ. Если нужно, попробуйте установить настройки таким образом, чтобы индексирование соответствовало полосам аппаратных векторов; это то, что ожидает большинство векторных программистов (по моему опыту).

Ответ 2

Разве это не согласуется с малой версией x86-оборудования? Способ хранения байтов длинной длины.

Ответ 3

В зависимости от того, что вы хотели бы сделать, вы можете использовать либо _mm_set_ps, либо _mm_setr_ps.

__ m128 _mm_setr_ps (float z, float y, float x, float w) Устанавливает четыре значения SP FP для четырех входов в обратном порядке.