C++ 在构造函数中复制m256d会导致SEGFULT
下面的代码是导致我在代码中看到的错误的简化案例。当我手动调用C++ 在构造函数中复制m256d会导致SEGFULT,c++,g++,stdvector,intrinsics,avx,C++,G++,Stdvector,Intrinsics,Avx,下面的代码是导致我在代码中看到的错误的简化案例。当我手动调用A(const A&)的构造函数时,一切都很好,但是当我尝试将一个vector复制到另一个A(const A&in):vec(in.vec){}行时,我得到一个segfault 为什么会发生这种情况,我如何处理我的代码 编辑:所以我添加了@mpromonet的代码,它现在运行到完成,但是1。速度要慢得多(超过3倍的系数)和2。当我使用-pg进行编译以找出原因时,在调用\u mm256\u add\u pd时,我得到一个segfault
A(const A&)
的构造函数时,一切都很好,但是当我尝试将一个vector
复制到另一个A(const A&in):vec(in.vec){}
行时,我得到一个segfault
为什么会发生这种情况,我如何处理我的代码
编辑:所以我添加了@mpromonet的代码,它现在运行到完成,但是1。速度要慢得多(超过3倍的系数)和2。当我使用-pg
进行编译以找出原因时,在调用\u mm256\u add\u pd
时,我得到一个segfault
#include <immintrin.h>
#include <vector>
using std::vector;
struct A {
union {
struct {
double a, b, c;
};
__m256d vec;
};
A() : a(0), b(0), c(0) {}
A(const A& in) : vec(in.vec) {}
};
int main() {
vector<A> e(10);
vector<A> b;
b = e;
}
无AVX
struct Vector {
double x;
double y;
double z;
Vector(double a, double b, double c) :
x(a), y(b), z(c)
{}
Vector(const Vector& u) :
x(u.x), y(u.y), z(u.z)
{}
Vector(const UnitVector& u);
Vector operator*=(const double m) { x*=m; y*=m; z*=m; return *this; }
Vector operator+=(const Vector& in) {
x+=in.x; y+=in.y; z+=in.z;
return *this;
}
ostream& operator<<(ostream& os) {
os << "x:" << x << " y:" << y << " z:" << z;
return os;
}
};
Vector::Vector(const UnitVector& u) :
x(u.x*u.mag), y(u.y*u.mag), z(u.z*u.mag)
{}
结构向量{
双x;
双y;
双z;
向量(双a、双b、双c):
x(a),y(b),z(c)
{}
向量(常量向量和u):
x(u.x)、y(u.y)、z(u.z)
{}
向量(常数单位向量&u);
向量运算符*=(常数双m){x*=m;y*=m;z*=m;返回*this;}
向量运算符+=(常量向量和输入){
x+=in.x;y+=in.y;z+=in.z;
归还*这个;
}
ostream&operator问题在于,系统的分配器不能保证32B对齐,这是编译器为_m256d类型所假定的 听起来您的目标是clang?如果是,请执行以下操作:
typedef double __attribute__((vector_size(32),aligned(16))) m256d_unaligned;
然后在结构定义中使用以下内容:
m256d_unaligned vec;
告诉编译器不要假设向量是对齐的。(如果您所在的系统甚至不能保证16B对齐,则可能需要进一步减少对齐参数)
更具侵入性(但可能更有效)解决方案是使用一个自定义的分配器,保证对需要它的类型进行32B对齐。我认为这是因为vector处理内存的方式-可能存在指针未对齐,但对象肯定未对齐。有点可怕的是,新的编译器有时会在所有情况下发出未对齐的访问。因此,虽然它不会ash,你可能会受到性能上的打击。最糟糕的是,你甚至都不知道。看起来
\uuuum256d
只是双精度上的一个typedef,带有\uuuuuu属性((\uu向量大小\uuu32)))
@Mysticial:如果内存对齐,vmovups
的速度与vmovaps
的速度一样快;唯一的区别是当数据未对齐时它不会崩溃。使用vmovaps
的唯一原因是为了强制对齐。@StephenCanon是的。我想要的是强制执行。但是最新的VS和ICCOMPILER总是使用vmovups
。所以我甚至不知道什么时候有些东西没有对齐(事实上,我的目标是g++4.8。这会改变什么吗?我相信,但我不确定,这也适用于最近的GCC。好的,我会试试。现在我只是在程序集中用vmovupd
替换vmovupd
,它正在运行;尽管速度很慢。不幸的是,尝试以这种方式对齐它不起作用,所以我继续使用它。)我确保分配32字节对齐的d数组。现在没有错误。但是速度非常慢,没有AVX内部函数时为13.5秒,有AVX内部函数时为71秒。知道为什么吗?我添加了代码中最长的部分,而不是粘贴整个问题。
typedef double __attribute__((vector_size(32),aligned(16))) m256d_unaligned;
m256d_unaligned vec;