Live data from Hacker News

GCC always assumes aligned pointer accesses (2020)

trust-in-soft.com

61–70 of 128 posts

Re: GCC always assumes aligned pointer accesses (2020)

#61
post #23

Earlier quoted context omitted.

Honestly, I think you are both incorrect. C has always had a concept of implementation defined behavior, and unaligned memory accesses used to be defined to work correctly on x86. Intel added instructions that can’t handle unaligned access, so they broke that contract. I’d argue that it is an instruction set architecture bug. Alternatively, Intel could argue that compilers shouldn’t emit vector instructions unless th…

Unaligned memory accesses are undefined behavior in C. If you're writing C, you should be abiding by C rules. "Used to work correctly" is more guesswork and ignorance than "abiding by C rules". In C, playing fast&loose with definitions hurts, BAD. Frankly, I'd be ashamed to write this blog post since the only thing it accomplishes is exposing its writers as not understanding the very thing they're signaling expertise…

What makes you think they don't understand it? They acknowledge that it is UB. I read them as realistic, since they know that people rely on C compilers working a certain way. They even wrote an interpreter that detects UB: https://github.com/TrustInSoft/tis-interpreter

I understand why people like the compiler being able to leverage UB. I suspect this philosophy actually makes Trust-In-Soft more money: You could argue that if there was no UB, there would be no need for the tis-interpreter.

So isn't it in fact quite self-less that they encourage the world to optimize a bit less (spending more money on 'compute'), while standing to profit from the unintended behaviour they'd otherwise be contracted to help debug?

Re: GCC always assumes aligned pointer accesses (2020)

#62
post #22
post #15

Earlier quoted context omitted.

Both gcc and clang will optimize a memcpy to an unaligned load/store where possible.

If the compiler is so smart, I guess it could insert a memcpy when needed? The standard, you may say.. I would argue it's the standard need to be changed. The modern reading of the standard is not useful as a low-level language and is unsafe as a high-level language.

> If the compiler is so smart, I guess it could insert a memcpy when needed?

If I'm reading your comment and the blog post correctly, the compiler would need a memory like access on every multibyte pointer argument where the compiler cannot otherwise prove alignment. Is that correct?

Re: GCC always assumes aligned pointer accesses (2020)

#63
post #2

The arguments in this blogpost are fundamentally flawed. The fact that they opened a bug based on them but got shut down should have raised all red flags. When compiling and running a C program, the only thing that matters is "what the C abstract machine does". Programs that exhibit UB in the abstract machine are allowed to do "anything". Trying to scope that down using arguments of the form "but what the hardware do…

The blog post is also kind of unhinged because in the incredibly rare cases where you would want to write code like this you can literally just use the asm keyword. I think it's also worth considering WHY compilers (and the C standard) make these kinds of assumptions. For starters, not all hardware platforms allow unaligned accesses at all. Even on x86 where it's supported, you want to avoid doing unaligned reads at…

While the sentiment is correct as to why compilers makes alignment assumptions, a lot of the details here I think are not quite right.

> For starters, not all hardware platforms allow unaligned accesses at all

If you're dealing with very simple CPUs like the ARM M0, sure. But even the M3/M4 allows unaligned access.

> Even on x86 where it's supported, you want to avoid doing unaligned reads at all costs because they're up to 2x slower than aligned accesses

I believe that information hasn't been true for a long time (since 1995). Unless you're talking about unaligned accesses that also cross a cache line boundary being slower [1]. But I imagine that aligned accesses crossing a cache line boundary are also similarly slower because the slowness is the cache line boundary.

> God forbid you try to use unaligned atomics, because while technically supported by x86 they're 200x slower than using the LOCK prefix with an aligned read

What you're referring to is atomic unaligned access that's also across cache line boundaries. I don't know what it is within a cache line, but I imagine it's not as bad as you make it out to be. Unaligned atomics across cache line boundaries also don't work on ARM and have much spottier support than unaligned access in general.

TLDR: People cargo cult advice about unaligned access but it's more because it's a simpler rule of thumb and there's typically very little benefit to pack things as tightly as possible which is where unaligned accesses generally come up.

[1] https://news.ycombinator.com/item?id=10529947

Re: GCC always assumes aligned pointer accesses (2020)

#64
post #23
post #2

The arguments in this blogpost are fundamentally flawed. The fact that they opened a bug based on them but got shut down should have raised all red flags. When compiling and running a C program, the only thing that matters is "what the C abstract machine does". Programs that exhibit UB in the abstract machine are allowed to do "anything". Trying to scope that down using arguments of the form "but what the hardware do…

Honestly, I think you are both incorrect. C has always had a concept of implementation defined behavior, and unaligned memory accesses used to be defined to work correctly on x86. Intel added instructions that can’t handle unaligned access, so they broke that contract. I’d argue that it is an instruction set architecture bug. Alternatively, Intel could argue that compilers shouldn’t emit vector instructions unless th…

> C has always had a concept of implementation defined behavior, and unaligned memory accesses used to be defined to work correctly on x86.

There are a bunch of misconceptions here:

- unaligned loads were never implementation defined, they are undefined;

- even if they were implementation defined, this would give the compiler the choice of how to define them, not the instruction set;

- unaligned memory accesses on x86 for non-vector registers still work fine, so old instructions were not impacted and there's no bug. It's just that the expectations were not fulfilled for the new extension of those instructions.

Re: GCC always assumes aligned pointer accesses (2020)

#65

Earlier quoted context omitted.

It dates to the first standardization of C in 1989. The "C as portable assembly" view ended when ANSI C got standardized, and K&R's 2nd edition was published.

For C to be portable this needs to be undefined behaviour because there are CPUs that don’t support unaligned access

That’s why, while much of the linked blog is kind of off the mark (signs of someone knowing less than they think they know), the general conclusion, using aligned pointers is recommended, is one that I typically recommend to developers new to C or C++ anyway.

I’m alright with folks sticking to aligned pointer operations, largely for performance reasons. On some platforms, unaligned operations are really expensive.

Re: GCC always assumes aligned pointer accesses (2020)

#66

Compilers should just add a --k&r mode to appease these people, but it should also reject ansi code with parse errors.

If a --k&r mode were to be reliable, wouldn't it need to get specified first? Otherwise people would start relying on some edge case.

If speed is not a requirement for the --k&r mode, you could just take the tis-interpreter and note that if it runs without UB, it is still much faster than an actual computer was when k&r were active.

Would it even be possible to specify a variant of C that contains no UB (e.g. would define exactly what happens on unaligned access), but can compile practical existing C89 programs? I wonder if it could be written such that it could actually specify the behaviour consistently across the language intersection supported by both of e.g. GCC 2.95 and Chibicc[0].

Or maybe there are so many bugs in GCC 2.95 that it would simply be infeasible? How much time would it take to specify?

[0]: https://github.com/rui314/chibicc

Re: GCC always assumes aligned pointer accesses (2020)

#67
post #2

The arguments in this blogpost are fundamentally flawed. The fact that they opened a bug based on them but got shut down should have raised all red flags. When compiling and running a C program, the only thing that matters is "what the C abstract machine does". Programs that exhibit UB in the abstract machine are allowed to do "anything". Trying to scope that down using arguments of the form "but what the hardware do…

The blog post is also kind of unhinged because in the incredibly rare cases where you would want to write code like this you can literally just use the asm keyword. I think it's also worth considering WHY compilers (and the C standard) make these kinds of assumptions. For starters, not all hardware platforms allow unaligned accesses at all. Even on x86 where it's supported, you want to avoid doing unaligned reads at…

> For starters, not all hardware platforms allow unaligned accesses at all.

Yeah and always everywhere a mistake. It was a mistake back in the 1970's and it's increasing bigger mistake as time goes on. Just like big endian and 'network order'

Re: GCC always assumes aligned pointer accesses (2020)

#68
post #19

Earlier quoted context omitted.

I would argue it's the modern understanding of C standard is flawed. Back in 89, many of those unspecified behavior were understood as implementation/hardware dependent, not undefined. Aliasing was the norm, `restrict` was actually a keyword. Modern C is neither safe nor low-level.

I haven't gotten to use C in industry, but I was taught that undefined behavior just means that it is defined by the running system and not the compiler. Is that not the general understanding? Maybe I was just taught that way because it was old timers teaching it.

What you are talking about is implementation-defined behavior. It exists in the C standard separately from the undefined behavior.

Re: GCC always assumes aligned pointer accesses (2020)

#70
post #23

Earlier quoted context omitted.

Honestly, I think you are both incorrect. C has always had a concept of implementation defined behavior, and unaligned memory accesses used to be defined to work correctly on x86. Intel added instructions that can’t handle unaligned access, so they broke that contract. I’d argue that it is an instruction set architecture bug. Alternatively, Intel could argue that compilers shouldn’t emit vector instructions unless th…

> C has always had a concept of implementation defined behavior, and unaligned memory accesses used to be defined to work correctly on x86. There are a bunch of misconceptions here: - unaligned loads were never implementation defined, they are undefined; - even if they were implementation defined, this would give the compiler the choice of how to define them, not the instruction set; - unaligned memory accesses on x8…

Note: SIMD on x86 has unaligned instructions that used to be much slower (decoded differently) than their aligned counterparts.

For example, on Pentium 3 and Pentium Core 2, the unaligned instructions took twice as many cycles to execute. On modern x86 family processors, it’s the same cycle count either way. The only perf penalty one should account for is crossing of cache lines, generally a much smaller problem.

Post reply on HN