I am rewriting some c++ code (originally written in Matlab as a MEX function) in codeblocks so that I can use debugging and profiling tools designed for c++. The code I am rewriting uses Eigen and SIMD intrinsic instructions, so I need to compile with the -march=native
flag. I was getting a memory access violation error when running my main project. Here is a slimmed down version of the code that causes the issue:
#include <iostream>
#include <fstream>
#include <string>
#include <sys/stat.h>
#include <immintrin.h>
#include <Eigen/Dense>
#include "Parameters.h"
using namespace std;
int main()
{
Parameters p;
p.na = 16;
p.TXangle = Eigen::VectorXd::LinSpaced(p.na,0,p.na-1);
cout << p.TXangle << endl;
cout << "Hello world!" << endl;
return 0;
}
where Parameters is a custom class defined with the following two files:
Parameters.h
#ifndef PARAMETERS_H_INCLUDED
#define PARAMETERS_H_INCLUDED
class Parameters
{
public:
int na;
Eigen::VectorXd TXangle;
Parameters();
};
#endif // PARAMETERS_H_INCLUDED
Parameters.cpp
#include <string>
#include <Eigen/Dense>
#include "Parameters.h"
Parameters::Parameters()
{
//ctor
}
The line that's breaking is when p.TXangle is initialized. At that point, the program throws the (0xC0000005) error. If I don't compile with '-march=native' then the error doesn't happen and the program runs fine. When building with '-march=native' I also get several alignment warnings. My computer supports upto AVX2 instructions and I'm compiling with MinGW GCC (not sure how to check the version of gcc on codeblocks).
gcc version is 8.1.0
Update: Is this the value @Sedenion was asking about in the comments?
This is the exact line the debugger stops at:
**Update: ** Based on the discussion in the comments, the disassembler shows that the code is at this assembly instruction when it fails:
I'm struggling to interpret this, reading assembly is still a bit new to me. Here are the registers at that same point:
-march=native
. I don't know how godbolt would handle that flag since it's compiled on a server – Inculpablemain
andparameters.cpp
with-march=native
? – Posse-march=native
flag – InculpableMemory.h
are of interest. The key to watch out for is if the allocated memory is aligned to 32 in case AVX is enabled (which should be the case here). Also check the value of theEIGEN_IDEAL_MAX_ALIGN_BYTES
macro inConfigureVectorization.h
: Is it 32? – Sherfield-std=c++17
) since it comes with some improvements regarding alignment features that Eigen uses. – Sherfieldalignas(32)
does work on them), but GCC mis-compiling code that uses__m256i
temporaries at all if it ever spills/reloads any (which will usevmovaps
orvmovdqa
; alignment required). Windows clang doesn't have this bug. But it's also possible that misalignment of data arrays is a problem though, if Eigen uses aligned stores. – Physicianvmovaps
(vmovapd
) orvmovdqa
command on the line where the program fails, then this bug in GCC you mention is what's tripping me up? – Inculpablevmovaps
/d orvmovdqa
with a memory operand using[rsp +- something]
then it's this bug. (Or[rbp +- something]
in a function that set up RBP as a frame pointer and is using it for local vars.) If you manually used_mm256_store_ps
on an array without doingalignas(32)
on it, you could in theory get that code, but on non-Windows GCC notices when you do that and over-aligns the array, IIRC. – Physician