我有一个函数,如下所述,我想在(1)
和non-temporal store
行中编写相同的行为。在(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 *
应该是好的。
或者我可以使用其他固有存储吗?
仅在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
通常会导致性能下降,除非你为结构体的每个元素调用这个或其他包装器函数。