Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSE and C++ containers

Is there an obvious reason why the following code segfaults ?

#include <vector>
#include <emmintrin.h>

struct point {
    __m128i v;

  point() {
    v = _mm_setr_epi32(0, 0, 0, 0);
  }
};

int main(int argc, char *argv[])
{
  std::vector<point> a(3);
}

Thanks

Edit: I'm using g++ 4.5.0 on linux/i686, I might not know what I'm doing here, but since even the following segfaults

int main(int argc, char *argv[])
{
  point *p = new point();
}

I really think it must be and alignment issue.

like image 622
andreabedini Avatar asked Mar 07 '11 05:03

andreabedini


1 Answers

The obvious thing that could have gone wrong would be if v wasn't aligned properly.

But it's allocated dynamically by vector, so it isn't subject to stack misalignment issues.

However, as phooji correctly points out, a "template" or "prototype" value is passed to the std::vector constructor which will be copied to all the elements of the vector. It's this parameter of std::vector::vector that will be placed on the stack and may be misaligned.

Some compilers have a pragma for controlling stack alignment within a function (basically, the compiler wastes some extra space as needed to get all locals properly aligned).

According to the Microsoft documentation, Visual C++ 2010 should set up 8 byte stack alignment automatically for SSE types and has done so since Visual C++ 2003

For gcc I don't know.


Under C++0x, for new point() to return unaligned storage is a serious non-compliance. [basic.stc.dynamic.allocation] says (wording from draft n3225):

The allocation function attempts to allocate the requested amount of storage. If it is successful, it shall return the address of the start of a block of storage whose length in bytes shall be at least as large as the requested size. There are no constraints on the contents of the allocated storage on return from the allocation function. The order, contiguity, and initial value of storage allocated by successive calls to an allocation function are unspecified. The pointer returned shall be suitably aligned so that it can be converted to a pointer of any complete object type with a fundamental alignment requirement (3.11) and then used to access the object or array in the storage allocated (until the storage is explicitly deallocated by a call to a corresponding deallocation function).

And [basic.align] says:

Additionally, a request for runtime allocation of dynamic storage for which the requested alignment cannot be honored shall be treated as an allocation failure.

Can you try a newer version of gcc where this might be fixed?

like image 50
Ben Voigt Avatar answered Nov 15 '22 17:11

Ben Voigt