非临时存储_mm_stream_si64的用法正确性验证及替代指令咨询
关于_mm_stream_si64用法及非临时存储替代方案的问题解答
原代码行(2)的用法是否正确?
不正确,原因如下:
- 类型不匹配:
_mm_stream_si64的函数原型要求第一个参数是__int64*,第二个参数是__int64,但你的代码直接传入void*类型的dest和src,属于不符合函数原型的隐式类型转换,会触发编译器警告,甚至在严格编译模式下报错。 - 虽然64位系统中
void*和__int64的内存宽度一致,隐式转换后可能能运行,但这属于实现定义行为,不具备可移植性,且不符合C标准的类型安全要求。
要正确复现行(1)的逻辑,需要对参数做显式类型转换,修正后的代码如下:
void func(void *dest, void *src){ (1) *(void **)(dest) = src; // 修正后的非临时存储写法 (2) _mm_stream_si64((__int64*)dest, (__int64)src); }
修正后,在64位系统下,该行代码会将src指针的数值以非临时存储的方式写入dest指向的内存,与行(1)的存储结果一致,但额外具备非临时存储的特性(绕过CPU缓存,直接写入内存,适合写入后短期内不被访问的数据)。
如果需要兼容32位系统,需根据指针宽度选择对应的intrinsic:
void func(void *dest, void *src){ *(void **)(dest) = src; #ifdef _WIN64 _mm_stream_si64((__int64*)dest, (__int64)src); #else _mm_stream_si32((__int32*)dest, (__int32)src); #endif }
其他可替代的非临时存储intrinsics指令
_mm_stream_si32:针对32位整数(或32位指针)的非临时存储,对应x86的MOVNTI指令,适合32位系统场景。_mm_stream_pd/_mm_stream_ps:分别针对双精度、单精度浮点数的非临时存储,对应MOVNTPD/MOVNTPS指令,不适合指针存储场景。- 若需要批量非临时存储,可使用编译器内置函数,比如GCC的
__builtin_memcpy_nontemporal,它会生成块非临时存储指令(如MOVNTDQA),效率比单个intrinsic循环更高。
内容的提问来源于stack exchange,提问作者Ana Khorguani
相关产品推荐
相关产品推荐

