Where can I find what the alignment requirement for any arbitrary compiler?
I came across this page The Lost Art of C Structure Packing and while I have never had to actually pad any structs, I'd like to learn a bit more so that when/if I need too - I can.
It says:
Storage for the basic C datatypes on an x86 or ARM processor doesn't normally start at arbitrary byte addresses in memory. Rather, each type except char has an alignment requirement; chars can start on any byte address, but 2-byte shorts must start on an even address, 4-byte ints or floats must start on an address divisible by 4, and 8-byte longs or doubles must start on an address divisible by 8. Signed or unsigned makes no difference.
Does this imply that all 32 bit processors (x86, ARM, AVR32, PIC32,...) have this alignment requirement? What about 16 bit processors?
If not, and it is device specific, where can I find this information? I tried searching through Microchip XC16 Manual but I could not find the alignment requirements that say that ints start at addresses divisible by 4.
I assume that the information is there, and I am not searching for the right key words - what is the "alignment requirement" called if I were to search online for more information?
Alignments requirements have 2 considerations: required, preferred
Required: Example: some platforms require various types, like an int
to be aligned. Contorted code that attempts to access an int
on an unaligned boundary results in a fault. Compilers will normally aligned data automatically to prevent this issue.
Efficiency: Unaligned accesses may be allowed yet results in slower code. Many compilers, rather than packing the data, will default to aligned data for speed efficiency. Typically such compilers allow a compiler specific keyword or compiler option to pack the data instead for space efficiency.
These issues apply to various processors of various sizes in different degrees. An 8-bit processor may have a 16-bit data bus and oblige 16+ -bit types to be aligned. A compliant C compiler for a 64-bit processor may have only have 64-bit types, even char
. The possibilities are vast.
C provides an integer type max_align_t
in <stddef.h>
. This could be used in various ways to determine the minimum general alignment requirement.
... max_align_t
which is an object type whose alignment is as great as is supported by the implementation in all contexts; ... C11 §7.19 2
C also has _Alignas()
to impose stricter alignment of a variable.
There are two global answers here. Yes, all processors have an alignment penalty of some sort (ARM, MIPS, x86, etc). No you cannot determine by type. All ARMs do not have the same alignment penalty, despite what folks think they know about the older ARMv4 and ARMv5, you could do unaligned accesses in a predictable way, that predictable way was not what most of us would have preferred, and you have to enable it. MIPS and ARMs and perhaps others at one point would have a severe punishment for unaligned transfers, you would get a data fault. But due to the nature of how programmers program, etc, the default at least for ARM is to have that disabled on some/newer cores. You can disable it or enable it whichever way you want.
ALL processors have a penalty for unaligned transfers, a performance penalty, and those hits happen at the various layers, sometimes in the core, at the edge of the core, on each cache layer, and at the outer layer of ram. Since the designs vary so widely you cannot come up with a single rule.
Likewise since alignment in compilers is implementation defined, you cant write portable code. So if you are dealing with a processor (likely an ARM since that is where most folks get bitten) that has unaligned faults enabled, the most portable solution, but not foolproof, is to start your structs with the 64 bit variables, then the 32 then the 16 then the 8. Compilers tend to place things in the order that you defined them, so long as the whole struct starts on the right boundary for that target, then the variables will fall into alignment properly, no padding required. There is no global solution to the problem other than dont use structs, or disable alignment checking and suffer the front end performance hits.
Note that the 32 bit arms we generally deal with today use a 64 bit AMBA/AXI bus not 32, they still can check all the alignments (16, 32, 64) for transfers if enabled, but the unaligned performance hits at least at the AMBA/AXI level dont hit you unless you cross the 64 bit aligned boundary. You may still have an extra cache line hit, although that is unlikely if you dont have an AMBA/AXI hit.
链接地址: http://www.djcxy.com/p/54092.html上一篇: C ++中未对齐访问的正确性
下一篇: 我在哪里可以找到任何编译器的对齐要求?