C语言 “内存对齐 8 个字节”是什么意思?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2846914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is meant by "memory is 8 bytes aligned"?
提问by Renjith G
While going through one project, I have seen that the memory data is "8 bytes aligned". Can anyone please explain what this means?
在进行一个项目时,我看到内存数据是“8 个字节对齐的”。谁能解释一下这是什么意思?
回答by caf
An object that is "8 bytes aligned" is stored at a memory address that is a multiple of 8.
“8 字节对齐”的对象存储在 8 的倍数的内存地址中。
Many CPUs will only load some data types from aligned locations; on other CPUs such access is just faster. There's also several other possible reasons for using memory alignment - without seeing the code it's hard to say why.
许多 CPU 只会从对齐的位置加载某些数据类型;在其他 CPU 上,这种访问速度更快。使用内存对齐还有其他几个可能的原因 - 没有看到代码很难说为什么。
Aligned access is faster because the external bus to memory is not a single byte wide - it is typically 4 or 8 bytes wide (or even wider). This means that the CPU doesn't fetch a single byte at a time - it fetches 4 or 8 bytes starting at the requested address. As a consequence of this, the 2 or 3 least significant bits of the memory address are not actually sent by the CPU - the external memory can only be read or written at addresses that are a multiple of the bus width. If you requested a byte at address "9", the CPU would actually ask the memory for the block of bytes beginning at address 8, and load the second one into your register (discarding the others).
对齐访问速度更快,因为到内存的外部总线不是单字节宽 - 通常为 4 或 8 字节宽(甚至更宽)。这意味着 CPU 一次不会获取一个字节 - 它从请求的地址开始获取 4 或 8 个字节。因此,内存地址的 2 或 3 个最低有效位实际上不是由 CPU 发送的 - 外部存储器只能在总线宽度倍数的地址处读取或写入。如果您在地址“9”处请求一个字节,CPU 实际上会向内存询问从地址 8 开始的字节块,并将第二个字节加载到您的寄存器中(丢弃其他字节)。
This implies that a misaligned access can require tworeads from memory: If you ask for 8 bytes beginning at address 9, the CPU must fetch the 8 bytes beginning at address 8 as well as the 8 bytes beginning at address 16, then mask out the bytes you wanted. On the other hand, if you ask for the 8 bytes beginning at address 8, then only a single fetch is needed. Some CPUs will not even perform such a misaligned load - they will simply raise an exception (or even silently load the wrong data!).
这意味着未对齐的访问可能需要从内存中读取两次:如果您要求从地址 9 开始的 8 个字节,则 CPU 必须获取从地址 8 开始的 8 个字节以及从地址 16 开始的 8 个字节,然后屏蔽掉你想要的字节数。另一方面,如果您要求从地址 8 开始的 8 个字节,则只需要一次提取。一些 CPU 甚至不会执行这种未对齐的加载——它们只会引发异常(甚至默默地加载错误的数据!)。
回答by Patrick Schlüter
The memory alignment is important for performance in different ways. It has a hardware related reason. Since the 80s there is a difference in access time between the CPU and the memory. The speed of the processor is growing faster than the speed of the memory. This difference is getting bigger and bigger over time (to give an example: on the Apple II the CPU was at 1.023 MHz, the memory was at twice that frequency, 1 cycle for the CPU, 1 cycle for the video. A modern PC works at about 3GHz on the CPU, with a memory at barely 400MHz). One solution to the problem of ever slowing memory, is to access it on ever wider busses, instead of accessing 1 byte at a time, the CPU will read a 64 bit wide word from the memory. This means that even if you read 1 byte from memory, the bus will deliver a whole 64bit (8 byte word). The memory will have these 8 byte units at address 0, 8, 16, 24, 32, 40 etc. A multiple of 8. If you access, for example an 8 byte word at address 4, the hardware will have to read the word at address 0, mask the high 4 bytes of that word, then read word at address 8, mask the low part of that word, combine it with the first half and give that to the register. As you can see a quite complicated (thus slow) operation. This is the first reason one likes aligned memory access. I will give another reason in 2 hours.
内存对齐以不同的方式对性能很重要。它有一个硬件相关的原因。自 80 年代以来,CPU 和内存之间的访问时间存在差异。处理器的速度比内存的速度增长得更快。随着时间的推移,这种差异越来越大(举个例子:在 Apple II 上,CPU 的频率为 1.023 MHz,内存是该频率的两倍,CPU 为 1 个周期,视频为 1 个周期。现代 PC 可以工作在 CPU 上大约 3GHz,内存只有 400MHz)。解决内存变慢问题的一种方法是在更宽的总线上访问它,而不是一次访问 1 个字节,CPU 将从内存中读取一个 64 位宽的字。这意味着即使您从内存中读取 1 个字节,总线也会传送整个 64 位(8 字节字)。内存将在地址 0、8、16、24、32、40 等处具有这 8 个字节单元。 8 的倍数。例如,如果您访问地址 4 处的 8 字节字,则硬件必须读取该字在地址 0 处,屏蔽该字的高 4 字节,然后在地址 8 处读取字,屏蔽该字的低部分,将其与前半部分组合并将其提供给寄存器。正如您所看到的,这是一个非常复杂(因此很慢)的操作。这是人们喜欢对齐内存访问的第一个原因。我将在 2 小时内给出另一个原因。正如您所看到的,这是一个非常复杂(因此很慢)的操作。这是人们喜欢对齐内存访问的第一个原因。我将在 2 小时内给出另一个原因。正如您所看到的,这是一个非常复杂(因此很慢)的操作。这是人们喜欢对齐内存访问的第一个原因。我将在 2 小时内给出另一个原因。
回答by Phong
"X bytes aligned" means that the base address of your data must be a multiple of X. It can be used for using some special hardware like a DMA in some special hardware, for a faster access by the cpu, etc...
“X 字节对齐”意味着您的数据的基地址必须是 X 的倍数。它可用于在某些特殊硬件中使用某些特殊硬件,例如 DMA,以便 cpu 更快访问等...
It is the case of the Cell Processor where data must be 16 bytes aligned in order to be copied to/from the co-processor.
在单元处理器的情况下,数据必须对齐 16 字节才能复制到协处理器/从协处理器复制。
回答by Peixu Zhu
if the memory data is 8 bytes aligned, it means: sizeof(the_data) % 8 == 0.
generally in C language, if a structure is proposed to be 8 bytes aligned, its size must be multiplication of 8, and if it is not, padding is required manually or by compiler. some compilers provide directives to make a structure aligned with n bytes, for VC, it is #prgama pack(8), and for gcc, it is __attribute__((aligned(8))).
如果内存数据是 8 字节对齐的,则表示:sizeof(the_data) % 8 == 0。
一般在C语言中,如果一个结构体被建议为8字节对齐,那么其大小必须是8的乘法,如果不是,则需要手动或编译器进行填充。一些编译器提供指令使结构与 n 个字节对齐,对于 VC,它是#prgama pack(8),对于 gcc,它是__attribute__((aligned(8)))。

