使用AVX2的_mm256_i64gather_pd触发段错误,求排查解决
问题
尝试使用AVX2提供的gather内置函数时,代码运行触发段错误。相关代码如下:
double src[100]; // src initialization here int indices[10] = { 2, 10, 12, 13, 48, 60, 71, 79, 94, 97}; index = _mm256_loadu_si256(reinterpret_cast<__m256i const*>(indices)); elements = _mm256_i64gather_pd(reinterpret_cast<double const*>(src), index, 8); // Segmentation fault happens here
不确定问题出在哪里,由于类型是double,已将scale参数设为8,编译时已添加-mavx2编译选项。
解答
- 索引类型不匹配:
_mm256_i64gather_pd要求传入的索引是64位整数(int64_t),但当前使用的是32位int数组。将32位int加载到__m256i寄存器后,高位会被填充为0,而gather指令会把每个索引当作64位值计算内存地址,这会导致地址计算异常,触发段错误。 - 寄存器容量与数组长度不匹配:
__m256i是256位寄存器,最多容纳4个64位整数,但当前indices数组有10个元素。使用_mm256_loadu_si256加载时会越界读取内存(超出数组范围的内存区域可能非法),这也是段错误的诱因之一。
修复步骤:
- 将索引数组改为64位整数类型,且长度匹配寄存器容量:
int64_t indices[4] = {2, 10, 12, 13}; // 一次处理4个索引,符合__m256i的容量 - 正确加载索引寄存器:
__m256i index = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(indices)); - 若需处理全部10个索引,需分三次执行gather操作(4个+4个+2个),分别对应不同的索引组,避免寄存器容量不足导致的越界问题。
内容的提问来源于stack exchange,提问作者Mr. Noob
相关产品推荐
相关产品推荐

