Gcc 非时态加载(MOVTDQA)操作数类型、对齐方式和asm语法
我正试图使用Gcc 非时态加载(MOVTDQA)操作数类型、对齐方式和asm语法,gcc,assembly,simd,inline-assembly,avx,Gcc,Assembly,Simd,Inline Assembly,Avx,我正试图使用VMOVNTDQA指令在使用posix_memalign()分配的数据数组上执行非临时加载(假设这是通过更改库进行写合并),并对16B进行对齐。然而,我不断地犯错误。uint64和uint128分别为DEF long long和_int128类型。下面是一段代码片段: uint64* arr; posix_memalign((void**) &arr, 16, arr_size * sizeof(uint64)) uint128 b; //index is a uint64
VMOVNTDQA
指令在使用posix_memalign()
分配的数据数组上执行非临时加载(假设这是通过更改库进行写合并),并对16B进行对齐。然而,我不断地犯错误。uint64和uint128分别为DEF long long和_int128类型。下面是一段代码片段:
uint64* arr;
posix_memalign((void**) &arr, 16, arr_size * sizeof(uint64))
uint128 b;
//index is a uint64 type and calculated earlier
asm volatile ("vmovntdqa %1, %0" : "=x" (b) : "m" (arr[index]));
//additional code working on b here, result stored back to arr[index]
VMOVNTDQA
规范规定指令类型为VMOVNTDQA xmm1,m128
,地址必须是128位(16字节)对齐的。现在,上面的代码将地址与16B对齐。上述代码工作正常,如果arr if类型为uint128,则不会出现任何SEGFULTS。但是,如果64位元素数组对齐,我应该能够从中加载128位值
我的问题是segfault是否是由于m128仅接受_int128类型元素而发生的?还是一个对齐问题?或者上述asm语法是否存在问题
谢谢如果您的
索引
为奇数,则地址将不对齐。请注意,vmovntdqa
在当前CPU上没有任何特殊功能,除非您在WC内存(不可缓存的写入组合,如视频RAM)上使用它。实际posix_memalign
将只分配正常的WB内存。如果您想减少正常负载的缓存污染,请使用prefetchntdqa
。如果您可以mmap一些WC内存,那么这很好,尽管可能比WB内存上的SW NT预取性能低。此外,使用内部函数而不是内联asm。您可以为编译器生成的asm循环计算核心周期和/或时间(TSC引用周期);我们大多数进行性能调整的人都会例行地这样做。使用内联asm(希望)将导致相同的最终结果asm输出,如果编译器不能围绕asm语句进行优化,则会导致更糟的结果。没有“对齐内存”这样的东西。指令关心的唯一地址是您给出的地址。调整分配只会确保您有一个已知的起点。您仍然需要保持该对齐的偏移。