Live data from Hacker News

A bug story: data alignment on x86

pzemtsov.github.io

31–40 of 111 posts

Re: A bug story: data alignment on x86

#31
post #29

I'm taking assembly right now, and we're working on our first RISC project after spending all semester working with the x86. Why does RISC crash if the bytes are not aligned?

It costs a non trivial amount of transistors (when compared with an ascetic RISC core) to load words from arbitrarily aligned addresses. 'RISC' used to be about removing those kinds of features, although the term has been a bit bastardized since then).

Re: A bug story: data alignment on x86

#32
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.…

Have you actually tried and verified that? Reading the docs I've had an impression that it says that the "aligned" is for the alignment inside of the structures, and you here declare the simple type?

Re: A bug story: data alignment on x86

#33
Again someone who relies on undefined behavior. Casting pointer of wrong alignement is not a platform specific behavior, it's an undefined behavior. Relying on it is an error.

The author did not know "What Every C Programmer Should Know About Undefined Behavior": http://blog.llvm.org/2011/05/what-every-c-programmer-should-...

Another good link about that: http://blog.regehr.org/archives/213

Re: A bug story: data alignment on x86

#34
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.…

This is documented as not working[1] in all but the most recent GCC versions. E.g. gcc-5.4 documents:

> "The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well. See below."

but gcc-6.2 documentation adds:

> "When used as part of a typedef, the aligned attribute can both increase and decrease alignment, and specifying the packed attribute generates a warning."

FWIW, Clang has supported reducing alignment in this fashion for a few years now.

[1] it's possible (likely, even) that it has been working for a while but the documentation was only recently brought up to date; I haven't investigated too carefully.

Re: A bug story: data alignment on x86

#35
post #29

I'm taking assembly right now, and we're working on our first RISC project after spending all semester working with the x86. Why does RISC crash if the bytes are not aligned?

Depends on the processor. Some RISC systems won't generate a fault, but others will. Some of the non-faulting ones will load unaligned data correctly (even across page boundaries), while others will helpfully swizzle bytes around in the result for you, or ignore the low bits.

"It depends."

Re: A bug story: data alignment on x86

#36
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…

> yet somehow felt the need to restrict much of the SSE ones into aligned

Because it wasn't worth spending die space on that as opposed to other things that matter a lot more for performance, presumably.

Re: A bug story: data alignment on x86

#37
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?

Types in Rust have alignment as in C, and bad stuff may happen if you use unsafe code to violate alignment.

It seems that at present, if you want to generate an unaligned SSE2 load/store, you have to rely on modern memcpy (spelled copy_nonoverlapping in Rust) optimization. See the first reply to https://internals.rust-lang.org/t/unaligned-simd-sse2-in-par...

Re: A bug story: data alignment on x86

#38

Again someone who relies on undefined behavior. Casting pointer of wrong alignement is not a platform specific behavior, it's an undefined behavior. Relying on it is an error. The author did not know "What Every C Programmer Should Know About Undefined Behavior": http://blog.llvm.org/2011/05/what-every-c-programmer-should-... Another good link about that: http://blog.regehr.org/archives/213

If a particular compiler specified that casting pointers of wrong alignments causes a segfault, it'd be perfectly acceptable to rely on that behavior. The standard would consider it UB, but that compiler has defined that behavior sufficiently.

Note, though, that a compiler simply doing a particular thing now isn't good enough to specify it in the sense that I mean. The compiler writers would have to explain (in a blog post or the like) the behavior and that they plan to keep that behavior in all future versions.

Re: A bug story: data alignment on x86

#39
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.…

The correct and portable solution is to not use uint32_t, but to use uint8_t, and construct the integers manually.

Re: A bug story: data alignment on x86

#40
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.…

You also need the may_alias attribute to prevent other problems.

Data written as int may be read as char, but going the other way is usually a standards violation. (an exception being if you had used char to implement a memcpy-like function, but in that case you should expect compiler bugs to bite you)

Post reply on HN