4

我注意到在不使用技巧的情况下__m128可以按索引访问字段。gccunion

__m128 t;

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

我也可以__m128像数组一样加载:

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

这一切都符合gcc' 向量扩展。但是,这些可能在其他地方不可用。intel 编译器和 msvc 是否支持加载和访问功能?

4

3 回答 3

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 字节对齐的动态数组,请使用

float *a = (float*)_mm_malloc(sizeof(float)*n, 16); //MSVC, GCC, ICC, MinGW 
于 2013-10-25T11:59:44.840 回答
2

您也可以为此使用宏:

//Test to see if we are using MSVC as MSVC AVX types are slightly different to the GCC ones
#ifdef _MSC_VER 
#define GET_F32_AVX_MULTIPLATTFORM(vector,index) (vector).m256_f32[index]
#define GET_F64_AVX_MULTIPLATTFORM(vector,index) (vector).m256d_f64[index]
#else 
#define GET_F32_AVX_MULTIPLATTFORM(vector,index) (vector)[index]
#define GET_F64_AVX_MULTIPLATTFORM(vector,index) (vector)[index]
#endif
于 2021-09-15T21:04:42.307 回答
1

要加载__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 个编译器,但它的返回类型很疯狂,使用起来很痛苦。

于 2013-10-25T07:45:41.963 回答