AVX 循环矢量化错误
Error in AVX loop vectorization
当我尝试使用 AVX 获取数据时,出现运行时错误 - 分段错误:
int i = 0;
const int sz = 9;
size_t *src1 = (size_t *)_mm_malloc(sz*sizeof(size_t), 32);
size_t *src2 = (size_t *)_mm_malloc(sz*sizeof(size_t), 32);
size_t *dst = (size_t *)_mm_malloc(sz*sizeof(size_t), 32);
__m256 buffer = _mm256_load_si256(&src1[i]);
__m256 buffer2 = _mm256_load_si256(&src2[i+1]); //Segmentation fault in this line
//Something...
_mm256_store_si256(dst[i], buffer);
_mm_free(src1);
_mm_free(src2);
_mm_free(dst);
我通过使用 '_mm256_loadu_si256' 内部函数来解决问题。有人知道为什么会这样吗?
_mm*_load_*
内在函数仅适用于 aligned 数据,而 _mm*_loadu_*
内在函数允许您使用 unaligned[=26] =] 数据(性能损失)。
分段错误告诉您您尝试从内存加载到 AVX 寄存器的值没有在正确的边界上对齐。对于 256 位版本,值必须在 32 字节边界上对齐。
如果您不想支付加载未对齐值的性能损失,那么您需要确保这些值在 32 字节边界上正确对齐。您可以通过插入填充或使用强制对齐的注释来执行此操作。注释是特定于编译器的——在 GCC 上,你会使用类似 __attribute__((aligned(32)))
的东西,而在 MSVC 上,你会使用像 __declspec(align(32))
.
这样的东西
这里的问题是,第二次加载时的数组索引强制从未对齐的内存位置加载。 attribute/annotation 无法解决这个问题。您将不得不填充这些值。使用 size_t
作为指针类型可能是第一个错误。该类型应为 32 字节宽。
当我尝试使用 AVX 获取数据时,出现运行时错误 - 分段错误:
int i = 0;
const int sz = 9;
size_t *src1 = (size_t *)_mm_malloc(sz*sizeof(size_t), 32);
size_t *src2 = (size_t *)_mm_malloc(sz*sizeof(size_t), 32);
size_t *dst = (size_t *)_mm_malloc(sz*sizeof(size_t), 32);
__m256 buffer = _mm256_load_si256(&src1[i]);
__m256 buffer2 = _mm256_load_si256(&src2[i+1]); //Segmentation fault in this line
//Something...
_mm256_store_si256(dst[i], buffer);
_mm_free(src1);
_mm_free(src2);
_mm_free(dst);
我通过使用 '_mm256_loadu_si256' 内部函数来解决问题。有人知道为什么会这样吗?
_mm*_load_*
内在函数仅适用于 aligned 数据,而 _mm*_loadu_*
内在函数允许您使用 unaligned[=26] =] 数据(性能损失)。
分段错误告诉您您尝试从内存加载到 AVX 寄存器的值没有在正确的边界上对齐。对于 256 位版本,值必须在 32 字节边界上对齐。
如果您不想支付加载未对齐值的性能损失,那么您需要确保这些值在 32 字节边界上正确对齐。您可以通过插入填充或使用强制对齐的注释来执行此操作。注释是特定于编译器的——在 GCC 上,你会使用类似 __attribute__((aligned(32)))
的东西,而在 MSVC 上,你会使用像 __declspec(align(32))
.
这里的问题是,第二次加载时的数组索引强制从未对齐的内存位置加载。 attribute/annotation 无法解决这个问题。您将不得不填充这些值。使用 size_t
作为指针类型可能是第一个错误。该类型应为 32 字节宽。