2013-10-25 2 views
2

Я заметил, что доступ к полям __m128 по индексу возможен в gcc, без использования трюка union.Доступ к полям __m128 через компиляторы

__m128 t; 

float r(t[0] + t[1] + t[2] + t[3]); 

Я также могу загрузить __m128 так же, как массив:

__m128 t{1.f, 2.f, 3.f, 4.f}; 

Это все в соответствии с векторными расширениями gcc «s. Однако они могут быть недоступны в других местах. Поддерживаются ли функции загрузки и доступа, поддерживаемые компилятором Intel и msvc?

+0

Стандартный C++ не поддерживает SSE. На каких целевых платформах вас интересует? –

+0

Что такое трюк 'union' для доступа к полям __m128? – Blue

+0

@Выполните что-нибудь вроде: 'union vec {__m128 a; float b [4]; double c [2]; }; '. Это не гарантируется. – user1095108

ответ

2

Чтобы загрузить __m128, вы можете написать _mm_setr_ps(1.f, 2.f, 3.f, 4.f), который поддерживается GCC, ICC, MSVC и clang.

Насколько я знаю, clang и последние версии поддержки GCC получают доступ к полям __m128 по индексу. Я не знаю, как это сделать в ICC или MSVC. Я думаю, _mm_extract_ps работает для всех 4 компиляторов, но его тип возврата безумный, что делает его болезненным в использовании.

3

Если вы хотите, чтобы код работал с другими компиляторами, тогда не используйте расширения GCC. Используйте свойства set/load/store. _mm_setr_ps подходит для установки постоянных значений, но не должен использоваться в цикле. Для доступа к элементам я обычно сначала запоминаю значения в массиве, а затем читаю массив.

Если у вас есть массив a вы должны прочитать/хранить его в с

__m128 t = _mm_loadu_ps(a); 
_mm_storeu_ps(a, t); 

Если массив 16 байт выровнены вы можете использовать выровненную нагрузку/магазин, который немного быстрее на более новых системах, но много быстрее в старых системах.

__m128 t = _mm_load_ps(a); 
_mm_store_ps(a, t); 

Чтобы получить 16-байтовый выровненный память на стеке использовать

__declspec(align(16)) const float a[] = ...//MSVC 
__attribute__((aligned(16))) const float a[] ...//GCC, ICC 

Для 16-байтных выровненной dynamic arrays use:

float *a = (float*)_mm_malloc(sizeof(float)*n, 16); //MSVC, GCC, ICC, MinGW 
+0

Мне нравится адресация по индексу, так как это позволяет мне не делать эти надоедливые смены. Как насчет сдвигов? – user1095108

+0

Сдвиги? Вы храните массив и получаете доступ к массиву по индексу, как любой массив. –

+0

Ahh, теперь я понимаю, что вы имеете в виду ... От разборки я видел, что компилятор делает некоторое смещение xmm-регистров для реализации адресной адресации. – user1095108

Смежные вопросы