创建 avx 向量时的 Segfault

Posted

技术标签:

【中文标题】创建 avx 向量时的 Segfault【英文标题】:Segfault while creating a vector of avx vectors 【发布时间】:2015-06-04 01:12:05 【问题描述】:

对于我当前的项目,我需要创建一个 256 位 AVX 向量的向量。我用过

myVector = vector<__m256d>(nrVars(), _mm256_set1_pd(1.0));

一次运行良好,但在执行该行两次后,它给了我一个分段错误。我能够想出以下代码

vector<__m256d> temp;
__m256d entry = _mm256_set1_pd(1.0);
temp = vector<__m256d>(10, entry);
temp = vector<__m256d>(10, entry);

总是会产生分段错误。您能否向我解释一下为什么会出现这种情况以及我以后如何避免这个问题?

非常感谢!

附:即使这样也行不通:

myVector.clear();
myVector.reserve(nrVars());
for (size_t i=0; i<nrVars(); ++i) 
    myVector[i] = _mm256_set1_pd(1.0);

并回答 cmets。这是一个产生段错误的完整示例:

#include <vector>
#include "immintrin.h"

using namespace std;
int main(int argc, char **argv) 
    vector<__m256d> temp;
    __m256d entry = _mm256_set1_pd(1.0);
    temp = vector<__m256d>(10, entry);
    temp = vector<__m256d>(10, entry);
    return 0;

要了解 m256d 和我正在使用的功能,请查看英特尔内部网站 (https://software.intel.com/sites/landingpage/IntrinsicsGuide/)

【问题讨论】:

信息不足。提供一个完整的、最小的、可重现的、可编译的示例来演示问题,而不是随机选择代码的 sn-ps。使用 C++,错误可能会导致代码的一部分出现内存损坏,直到在其他地方访问受影响的内存时才会出现,从而触发段错误。仅仅因为您在特定位置出现段错误,就绝对没有说明代码的特定部分。尽管您发布的有用信息很少,但您的错误很可能在其他地方。欢迎使用 C++。 您需要发布更多关于此的信息:__m256d entry = _mm256_set1_pd(1.0); .. 更具体地说,__m256d 是什么,_mm256_set1_pd 的功能是什么? /跨度> __mm256d 是 AVX 中的标准类型,_mm256_set1_pd 是标准内在类型。他标记了问题 AVX,并且不需要解释基本面。如果您对某事没有经验,请不要责怪发帖者。 【参考方案1】:

AVX 需要对齐的数据。 vector 不保证元素会正确对齐。请参阅此问题 (How is a vector's data aligned?),了解分配对齐的讨论,特别是关于 SIMD 执行的讨论。

【讨论】:

谢谢,虽然这看起来实施起来会很痛苦......一旦我在我的机器上运行它就会接受你的回答 AVX 实际上不需要需要对齐的数据,除非编译器生成vmovaps 而不是vmovups。 AVX 非移动指令的内存操作数不必对齐。只有加载和存储移动指令的对齐版本才会出现段错误。不过,在某些方面,编译器会将未对齐数据设为错误,从而使您免于性能稍慢的问题,这很好。【参考方案2】:

在 C++17 中,std::vector 保证元素将正确对齐。

How is a vector's data aligned?

【讨论】:

老兄,5 年前有一个公认的答案,说的完全一样。你是机器人吗? @user667804 我不是机器人,我错了,对不起:/

以上是关于创建 avx 向量时的 Segfault的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AVX 向量中找到元素的索引?

仅包含 3 个元素的两个向量的 AVX 优化相加

2 个 AVX-512 向量元素的交错合并 - C 内在

SSE/AVX 向量类型的差异

将 SSE 矩阵向量乘法代码转换为 AVX

如何在两个 AVX2 向量之间交换 128 位部分