使用 SSE2 intrinsic 存储或提取标量 int 结果的更好方法
Better way to store or extract scalar int result using SSE2 intrinsic
我想知道在使用 SSE2 时如何有效地加载和存储变量。
在这个例子中,我想将 pclmulqdq
指令(进行较少的乘法运算,对多项式算术有用)与普通 C 函数放在一起,所以我需要与标准函数相同的“调用约定”。
a和b是16个有效位,结果将有32个有效位
#include <wmmintrin.h>
int GFpoly_mul_i(int a, int b) {
__m128i xa = _mm_loadu_si128( (__m128i*) a);
__m128i xb = _mm_loadu_si128((__m128i*) b);
__m128i r = _mm_clmulepi64_si128(xa, xb, 0);
_MM_ALIGN16 int result[4];
__m128i* ptr_result = (__m128i*)result;
_mm_store_si128(ptr_result, r);
return result[0];
}
从向量的最低部分提取 32 位整数可以很容易地完成 _mm_cvtsi128_si32
:
return _mm_cvtsi128_si32(r);
将一个 32 位整数加载到向量的最低部分可以用“相反”操作来完成,_mm_cvtsi32_si128
:
__m128i xa = _mm_cvtsi32_si128(a);
无法使用 _mm_loadu_si128( (__m128i*) a)
将整数 a
加载到向量中,这会将 a
转换为指针并取消引用它(读取 128 位向量),但是 a
只是一个整数值,没有指向任何有用的地方,除非可能是偶然的。
我想知道在使用 SSE2 时如何有效地加载和存储变量。
在这个例子中,我想将 pclmulqdq
指令(进行较少的乘法运算,对多项式算术有用)与普通 C 函数放在一起,所以我需要与标准函数相同的“调用约定”。
a和b是16个有效位,结果将有32个有效位
#include <wmmintrin.h>
int GFpoly_mul_i(int a, int b) {
__m128i xa = _mm_loadu_si128( (__m128i*) a);
__m128i xb = _mm_loadu_si128((__m128i*) b);
__m128i r = _mm_clmulepi64_si128(xa, xb, 0);
_MM_ALIGN16 int result[4];
__m128i* ptr_result = (__m128i*)result;
_mm_store_si128(ptr_result, r);
return result[0];
}
从向量的最低部分提取 32 位整数可以很容易地完成 _mm_cvtsi128_si32
:
return _mm_cvtsi128_si32(r);
将一个 32 位整数加载到向量的最低部分可以用“相反”操作来完成,_mm_cvtsi32_si128
:
__m128i xa = _mm_cvtsi32_si128(a);
无法使用 _mm_loadu_si128( (__m128i*) a)
将整数 a
加载到向量中,这会将 a
转换为指针并取消引用它(读取 128 位向量),但是 a
只是一个整数值,没有指向任何有用的地方,除非可能是偶然的。