我有一个函数,如下所述,我想用non-temporal store
写一个与(1)
行相同的行为。在(2)
行中使用_mm_stream_si64
是复制(1)
行的正确方法吗?
void func(void *dest, void *src){
(1) *(void **)(dest) = src;
(2) _mm_stream_si64(dest, src);
}
我不能完全确定我是否正确地使用了_mm_stream_si64
,因为它应该将__int64
类型作为第二个参数(_mm_stream_si64(__int64* mem_addr, __int64 a)
)。虽然对于mem_addr
,我希望使用void *
应该是可以的。
或者我可以使用其他的内在存储吗?
1条答案
按热度按时间92dk7w1h1#
它只在64位模式下是正确的,
void*
是64位的。但是,是的,这是正确的。它是一个8字节的需要对齐的存储,是严格别名安全的(它不关心C类型,只关心内存的字节,像memcpy一样,但有对齐要求。)所以,如果dst
正确对齐以保存void*
,它绝对是安全的。尽管具有64位操作数大小的
movnti
仅在64位模式下可用,因此唯一会编译但会出错的情况是使用gcc -mx32
(64位模式下的32位指针)。您应该包含
static_assert( sizeof(src) == sizeof(int64_t) )
。或者包含if(sizeof(src) == 4)
以选择_mm_stream_si32
。请注意,NT存储通常只有在使用NT存储 *(自然对齐的64字节块的所有64字节)写一整行 * 时才有效。因此,单个
movnti
通常会降低性能,除非您为结构体的每个元素调用这个或其他 Package 函数。