14 ms·
The Lost Art of C Structure Packing
- valarauca1 9y agoLost but not forgotten. IDK, most these rules are very trivial and fairly simple to automate. Pretty much boils down to declare the smallest fields first, with a handful of exceptions based on the modulus of size. Ultimately I like Rust’s approach. Without including ‘[repr(C)]/[repr(packed)]’ the compiler is free to layout the structure in the most efficient way for the target platform. And accessing fields with different compiler’s code is UB. You get the speed up, while keeping backwards compatibility. Sadly C/C++ are shackled to this archaic system. Also I believe Go, Nim, and Swift are as well (this is speculation).
- loeg 9y agoIt's not even lost. Any C code that cares about performance will eventually look into how structures are laid out in cache lines.
- valarauca1 9y agoIt is a requirement for code heavily using atomics as false shares and destroy performance.
- deleted 9y ago[deleted]
- millstone 9y agoIf switching compilers results in UB, how is that keeping backwards compatibility?
- valarauca1 9y ago`[repr(C)]` maintains compatibility with C-ABI, therefore keeping backwards compatibility with C, C++, Rust, etc. As the C ABI, and C structure layout rules are standardized across platforms.
- smeenai 9y agoclang-tidy has a struct padding check which diagnoses non-optimal struct orders, and a coworker contributed a clang tool to reorder fields: https://github.com/llvm-mirror/clang-tools-extra/tree/master/clang-reorder-fields https://github.com/llvm-mirror/clang-tools-extra/tree/master...
- nly 9y agoThis makes sense if you're only concerned with size. Locality or eliminating false sharing may be more important in large ones
- shortlived 9y agoNot lost if you are programming on a mainframe... just not blogged about.
- boznz 9y ago.. And not applicable to 8-bit embedded programmers.
- Sinergy2 9y agoAre you sure? You can still declare a short field on a 8b micro.
- FRex 9y agoWhat are the alignment requirements for one there though? Unaligned access can come with performance cost or be impossible on 16 and 32 bit machines for some cases (I don't know all the details for ARM and x86) but I'd assume (I don't definitely KNOW, just making an educated guess) that an 8 bit machine that can only do 8 bit operations doesn't need alignment at all and using a short (or a long) always involves reading 8 bits twice (or 4 times) and any 8 bits at all can be read so it can be packed completely tightly. Meanwhile (I'm again just guessing, I'm not low level enough to know that), 16 and 32 bit machines try to read it all in one go into a register and that's why they need alignment or else they take the performance hit to read twice and mask out the value or raise an exception. This art is certainly not lost though it comes up with language VMs, native compilers, Linux kernel, as a common curio about C and C++, etc.
- kevin_clever 9y agoI tried the example below, saved as `main.c`. It seems she automatically reorders the static mem. Can that behavior be disabled? Can someone please explain? #include<stdio.h> int main(int argc, char** argv) { char *p; char c; int x; printf("char p %p\n", &p); printf("char %p, offset %i\n", &c, (int)((void*)&c-(void*)&p)); printf("integer %p, offset %i\n", &x, (int)((void*)&x-(void*)&p)); return 0; } Output on `gcc main.c; ./a.out` char p 0x7ffc5107dff0 char 0x7ffc5107dfeb, offset -5 integer 0x7ffc5107dfec, offset -4
- kps 9y agoThose are not structure members. C provides no guarantees about the relative locations of separate variables.
- kevin_clever 9y agoSo, it's a compiler specific reordering?
- pjc50 9y agoYes. Probably specific to compiler options too. Only structure members have a defined order.
- sargun 9y agoAre there any guarantees about (re)use of stack addresses?
- sigjuice 9y agoNo. "Stack" is an implementation detail. I don't think the standard even mentions the word "stack" anywhere.
- sigjuice 9y agoSubtraction of arbitrary pointers is not legal.
- ryanmccullagh 9y agoHint, compile with -Wpacked
- ramzyo 9y agoHave to disagree with you here, totally depends on the platform and if you know what you’re doing. Compiling with this option can lead to unaligned memory accesses. On some architectures, most ARM ones for example, unaligned memory accesses lead to hard faults at runtime.
- smitherfield 9y agoYou're thinking of `#pragma pack`. `-Wpadded` just warns about non-optimal layout.
- ramzyo 9y agoWhoops, yes my bad. -Wpacked will just issue the warning, not actually do the packing!
- adrianN 9y agoWait, doesn't the compiler produce the appropriate code for accessing the packed values without using unaligned memory access if the target platform doesn't support that?
- justinplouffe 9y agoAwareness of the layout and size of data is still very common in game development. Mike Acton did a great talk related to this at CppCon a few years ago : https://www.youtube.com/watch?v=rX0ItVEVjHc https://www.youtube.com/watch?v=rX0ItVEVjHc
- jzelinskie 9y agoThis is true for high performance server software, too, especially servers that resemble databases. I personally find myself thinking about alignment more than I probably should. For Go, I use http://golang-sizeof.tips http://golang-sizeof.tips for experimenting. I've been able to make schema changes to my structs to enable more functionality without increasing memory usage.
- banned1 9y agoThis is going to sound rude but it is not my intention. The reality is that packing DOES NOT matter for most applications these days. I read an article about a person who was the last in the world to speak some obscure language. Some people wanted to start a school to teach others to speak that language, wanted the government to pay for it, etc. The two articles gave me the same combined feel of “I feel a little sorry but not a lot” and “who cares.” The compiler will take care of most. Unfortunately for that person on the other article, he is basically screwed. Don’t let that be you.
- abiox 9y agodepending on what you mean by "most applications", that's been the case for 20+ years. that said, compilers can't "take care" of a lot of things; and either way, people are still needed to develop and maintain those compilers. there will also always be software that has significant performance requirements, and opportunities to write higher performing software than competitors.
- xelxebar 9y agoOnly for certain values of "most". As the author mentions, kernels and embedded applications very often need to have tight control over memory layout.
- vardump 9y agoYou probably should not be using C.
- mar77i 9y agoUrm, the mere fact that somebody is capable to micro-manage every different aspect and detail about a program is purely theoretical, as nobody talks about actually doing so, or if, how often that is done. It just makes them a competent developer/computer scientist. Just like emergency protocols aren't used often by airplane pilots, doesn't mean they're completely useless. You may be right, as you'll never be trying to make a binary fit an artificially imposed size limit or things like this, as is sometimes necessary in the demo scene. In my experience, having aspiration always outweighs the ignorance of not having it. YMMV.
- 9y ago
- drake01 9y agoI've found file: unaligned-memory-access.txt useful. Ref:- Linux Kernel Source: UNALIGNED MEMORY ACCESSES Link: https://github.com/torvalds/linux/blob/master/Documentation/unaligned-memory-access.txt https://github.com/torvalds/linux/blob/master/Documentation/...