Live data from Hacker News

A bug story: data alignment on x86

pzemtsov.github.io

11–20 of 111 posts

Re: A bug story: data alignment on x86

#11
The correct solution for GCC is specifying 1-byte alignment for this particular array:

  #include 
  #include 

  typedef uint32_t __attribute__((__aligned__(1))) uint32_t_unaligned;

  uint64_t sum (const uint32_t_unaligned * p, size_t nwords)
  {
      uint64_t res = 0;
      size_t i;
      for (i = 0; i 
Probably works on clang too and IIRC the MS compiler provides similar functionality with different syntax. AFAIK there is no portable solution.

And I'm not sure how exactly this code will fail on architectures which don't support unaligned uint32_t.

Re: A bug story: data alignment on x86

#13
post #8

These SSE instructions that operate only on aligned data are a pain. It's not well known that Linux/x86 stack frames must always be 16 byte aligned. GCC uses this knowledge to use the SSE aligned instructions when accessing certain fields on the stack. Unfortunately a while back the OCaml compiler generated non-aligned stack frames. Which is no problem for pure OCaml code and even saves a little bit of memory. Howeve…

Agreed, I've always found them unusual and perhaps a bit of a shortsighted decision --- they've been making processors seamlessly handle any alignment with perhaps an extra cycle, even for the MMX instructions, yet somehow felt the need to restrict much of the SSE ones into aligned and only provide one unaligned move.

The stack alignment restriction is also annoying when handwriting Asm, although fortunately it's only when calling into other C libraries that it needs to be minded.

Re: A bug story: data alignment on x86

#15
post #11

The correct solution for GCC is specifying 1-byte alignment for this particular array: #include #include typedef uint32_t __attribute__((__aligned__(1))) uint32_t_unaligned; uint64_t sum (const uint32_t_unaligned * p, size_t nwords) { uint64_t res = 0; size_t i; for (i = 0; i Probably works on clang too and IIRC the MS compiler provides similar functionality with different syntax. AFAIK there is no portable solution.…

In C++11 there is a standard for this : http://en.cppreference.com/w/cpp/language/alignas

Re: A bug story: data alignment on x86

#16
post #8

These SSE instructions that operate only on aligned data are a pain. It's not well known that Linux/x86 stack frames must always be 16 byte aligned. GCC uses this knowledge to use the SSE aligned instructions when accessing certain fields on the stack. Unfortunately a while back the OCaml compiler generated non-aligned stack frames. Which is no problem for pure OCaml code and even saves a little bit of memory. Howeve…

Agreed, I've always found them unusual and perhaps a bit of a shortsighted decision --- they've been making processors seamlessly handle any alignment with perhaps an extra cycle, even for the MMX instructions, yet somehow felt the need to restrict much of the SSE ones into aligned and only provide one unaligned move. The stack alignment restriction is also annoying when handwriting Asm, although fortunately it's onl…

> seamlessly handle any alignment with perhaps an extra cycle

I'm not up to date on the latest mitigation strategies, but the hairball of cache implications caused by unaligned access make me suspicious of that claim. If you (or your compiler) signal that you want performance by using vector instructions, I think it's completely fair for Intel to demand that you pay attention to alignment.

Re: A bug story: data alignment on x86

#17
post #15
post #11

The correct solution for GCC is specifying 1-byte alignment for this particular array: #include #include typedef uint32_t __attribute__((__aligned__(1))) uint32_t_unaligned; uint64_t sum (const uint32_t_unaligned * p, size_t nwords) { uint64_t res = 0; size_t i; for (i = 0; i Probably works on clang too and IIRC the MS compiler provides similar functionality with different syntax. AFAIK there is no portable solution.…

In C++11 there is a standard for this : http://en.cppreference.com/w/cpp/language/alignas

Anybody knows how Rust handles this problem?

Re: A bug story: data alignment on x86

#19
post #17
post #15

Earlier quoted context omitted.

In C++11 there is a standard for this : http://en.cppreference.com/w/cpp/language/alignas

Anybody knows how Rust handles this problem?

Not sure if this is what you are asking: Last time I tried alignment in Rust I worked around the lack of explicit alignment support by adding a zero length array of the correct size to the end of the struct. Not sure if alignment support from proper attributes has landed yet.

   [repr(C)]
   struct Something
   {
      pub foo: f32,
      pub _alignment: [EightBytes, 0]
   }
where "EightBytes" is a data type of size 8, to align the whole struct on 8 bytes.

Re: A bug story: data alignment on x86

#20
post #15
post #11

The correct solution for GCC is specifying 1-byte alignment for this particular array: #include #include typedef uint32_t __attribute__((__aligned__(1))) uint32_t_unaligned; uint64_t sum (const uint32_t_unaligned * p, size_t nwords) { uint64_t res = 0; size_t i; for (i = 0; i Probably works on clang too and IIRC the MS compiler provides similar functionality with different syntax. AFAIK there is no portable solution.…

In C++11 there is a standard for this : http://en.cppreference.com/w/cpp/language/alignas

I think it doesn't work in this case because

If the strictest (largest) alignas on a declaration is weaker than the alignment it would have without any alignas specifiers (that is, weaker than its natural alignment or weaker than alignas on another declaration of the same object or type), the program is ill-formed.

Also, using alignas on pointer variable will probably specify alignment of the pointer itself, not the pointed object. I suppose you can create a wrapper class around int with alignas(32) and specify the pointer as pointing to that, but this is going to be nasty given that you can't derive from int and have to write all those operators by hand.

Post reply on HN