为什么填充必须是二的幂? [英] Why does padding have to be a power of two?

查看:135
本文介绍了为什么填充必须是二的幂?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一些示例程序,探索C和想知道为什么结构填充可在断电状态下进行的两只。

I am doing some sample programs to explore C and would like to know why structure padding can be done in power of two only.

#include <stdio.h>

#pragma pack(push, 3)

union aaaa
{

   struct bbb
   {
      int a;
      double b;
      char c;
   }xx;

   float f;
};

#pragma pack(pop)

int main()
{

printf("\n Size: %d", sizeof(union aaaa));

return 0;
}

在编写

warning: alignment must be a small power of two, not 3 [-Wpragmas]
warning: #pragma pack (pop) encountered without matching #pragma pack (push) [-Wpragmas]

看来的#pragma不起作用。输出只有24。即4字节对齐。

It seems #pragma has no effect. Output is 24 only. i.e 4 byte aligned.

推荐答案

简短的回答是,在处理器的基本对象必须是两个(如1,2,4,8,和16字节)小功率的大小和内存在基团,其大小是两个(例如,8字节)小的功率进行组织,因此结构必须对准与这些尺寸很好地工作。

The short answer is that basic objects in processors have sizes that are small powers of two (e.g., 1, 2, 4, 8, and 16 bytes) and memory is organized in groups whose size is a small power of two (e.g., 8 bytes), so structures must be aligned to work well with those sizes.

长的答复是,这种情况的原因在物理和初等数学接地。计算机自然与位工作,具有值0和1。这是因为它很容易设计出两个值之间切换物理事物:高电压和低电压,电荷,等等的电荷或不存在的presence。三个数值之间的区分是很难的,因为你必须要重视价值观之间的过渡更为敏感。这样,作为计算机技术在过去几十年的发展,我们已经使用的比特(二进制数字),而不是像三进制数字的替代方案。

The long answer is that the reasons for this are grounded in physics and elementary mathematics. Computers naturally work with bits, with values 0 and 1. This is because it is easy to design physical things that switch between two values: High voltage and low voltage, presence of a charge or absence of a charge, et cetera. Distinguishing between three values is harder, because you have to be more sensitive about transitions between values. So, as computer technology has developed over the decades, we have used bits (binary digits) instead of alternatives like trinary digits.

要做出更大的数字,我们结合多个位。所以两位能,结合起来,有四个值。三位可以有八个值,依此类推。在较旧的计算机,有时位六个组,十一次。然而,八成为普遍,而现在基本上是标准配置。使用八个位为一个字节没有强的物理原因,因为一些其他分组我描述的,但它是世界上的方式

To make larger numbers, we combine multiple bits. So two bits can, combined, have four values. Three bits can have eight values, and so on. In older computers, sometimes bits were group six or ten at a time. However, eight became common, and is essentially standard now. Using eight bits for a byte does not have as strong a physical reason as some of the other groupings I describe, but it is the way of the world.

计算机的另一个特征是存储器。一旦我们有了这些字节,我们要存储他们中的很多,在一个设备很容易接触到处理器内,所以我们可以得到很多字节进出处理器很快的。当我们有很多的字节,我们需要为处理器内存告知哪些字节处理器要读取或写入的方式。因此处理器需要一种方法,以解决字节

Another feature of computers is memory. Once we have these bytes, we want to store a lot of them, in a device that is easily accessible to the processor, so we can get lots of bytes into and out of the processor quickly. When we have a lot of bytes, we need a way for the processor to tell memory which bytes the processor wants to read or write. So the processor needs a way to address the bytes.

处理器使用比特值,因此它是将要使用的比特为地址值。所以内存将建接受位来指示哪些字节要提供给处理器当处理器读或哪些字节当处理器写到存储。什么是存储设备对这些位呢?一件容易的事情就是用一个位来控制途径之一切换到内存中。该内存将被做出来的存储字节的许多小的部分。

The processor uses bits for values, so it is going to use bits for address values. So the memory will be built to accept bits to indicate which bytes to supply to the processor when the processor reads or which bytes to store when the processor writes. What does the memory device do with those bits? An easy thing is to use one bit to control one switch of the pathways to memory. The memory will be made out of many small parts that store bytes.

考虑在存储设备中的事情,可以存储一个字节,并考虑两个那些东西相邻,说A和B,我们可以用一个开关来选择是否要在一个字节活跃或B字节被激活。现在考虑这些东西四,说A,B,C和D,我们可以使用一个开关来选择是否使用A-B组或使用C-D组。然后另一个开关选择A或B(如果使用的是A-B组)或C或D(如果使用的是C-D组)。

Consider a thing in the memory device that can store a byte, and consider two of those things next to each other, say A and B. We can use a switch to select whether we want the A byte to be active or the B byte to be active. Now consider four of those things, say A, B, C, and D. We can use one switch to select whether to use the A-B group or to use the C-D group. Then another switch selects A or B (if using the A-B group) or C or D (if using the C-D) group.

此过程继续进行:在一个存储器地址的每一位选择的一组存储单元来使用。 2店面单元之间的1位选择,4间2选择,8间3选择,16间4选择,等等。 8位256存储单元之间选择,24位16777216存储单元之间选择,以及32位4,294,967,296存储单元之间选择。

This process continues: Each bit in a memory address selects a group of storage units to use. 1 bit selects between 2 store units, 2 select between 4, 3 select between 8, 4 select between 16, and so on. 8 bits select between 256 storage units, 24 bits select between 16,777,216 storage units, and 32 bits select between 4,294,967,296 storage units.

有一个更复杂。移动处理器和存储器之间个别字节是缓慢的。相反,现代计算机内存整理成大块,比如八个字节。您只能在内存和处理器之间的时间移动八个字节。当处理器请求内存提供一些数据,处理器只发送地址的低三位内八个字节选择单个字节的高位,他们不会被发送到内存中。

There is one more complication. Moving individual bytes between the processor and memory is slow. Instead, modern computers organize memory into larger pieces, such as eight bytes. You can only move eight bytes at a time between memory and the processor. When the processor requests that memory supply some data, the processor only sends the high bits of the address—the low three bits select individual bytes within eight bytes, and they are not sent to memory.

这是更快,因为处理器获得八个字节进入一次,否则,需要有内存做所有的开关,以提供一个字节,它是便宜,因为你不需要额外的交换机数量庞大,将采取分辨单个字节在内存中。

This is faster because the processor gets eight bytes into the time it would otherwise take to have the memory do all its switching to supply one byte, and it is cheaper because you do not need the huge number of extra switches it would take to distinguish individual bytes in memory.

不过,现在它意味着处理器没有获得从内存中单个字节的方式。当执行访问单个字节的指令,处理器必须从内存中读取八个字节,然后游移在处理器内那些字节来得到你想要的一个字节。同样,让两个或四个字节,处理器读取八个字节,并提取你想要的字节数。

However, now it means the processor has no way of getting an individual byte from memory. When you execute an instruction that accesses an individual byte, the processor must read eight bytes from memory and then shift those bytes around inside the processor to get the one byte you want. Similarly, to get two or four bytes, the processor reads eight bytes and extracts just the bytes you want.

要简化这个过程,处理器设计者指定数据应以特定的方式排列。通常情况下,它们需要两个字节的数据(如16位整数),以对准的两个字节的倍数,四字节数据(如32位整数和32位浮点值),以对准的四的倍数字节和八个字节的数据被对准以八个字节的倍数。

To simplify this process, processor designers specify that data should be aligned in certain ways. Typically, they require two-byte data (like 16-bit integers) to be aligned to multiples of two bytes, four-byte data (like 32-bit integers and 32-bit floating-point values) to be aligned to multiples of four bytes, and eight-byte data to be aligned to multiples of eight bytes.

这需要调整有两方面的影响。第一,因为四字节数据可以在从存储器(开头或中间)读一个八字节块两个地方只启动,处理器设计者只需要把在电线从两个地方提取四个字节。他们不需要添加所有的额外的电线从任何如果任何取向被允许可能被开始的地方的八个单个字节中提取四个字节。 (有些处理器将全面禁止加载未经调整的数据,以及一些处理器将允许它,但使用慢速的方法来提取它使用更少的电线,但使用迭代算法将数据在多个处理器周期转变,所以未对齐的负载是缓慢的。)

This required alignment has two effects. First, because four-byte data can only start at two places in an eight-byte chunk read from memory (the beginning or the middle), the processor designers only need to put in wires to extract the four bytes from two places. They do not need to add all the extra wires to extract four bytes from any of the eight individual bytes that could be starting places if any alignment were allowed. (Some processors will completely prohibit loading unaligned data, and some processors will allow it but use slow methods to extract it that use fewer wires but use an iterative algorithm to shift the data over several processor cycles, so unaligned loads are slow.)

第二个效果是,因为四字节数据可以在一个八字节块两个地方只启动,也即组块内结束。试想,如果你试图加载四个字节即开始在八字节块的第六个字节的数据会发生什么。前两个字节是在组块,但接下来的两个字节是在存储器中的下一个块。处理器将不得不读取内存中的两个块,从每个人采取不同的字节,并把这些字节在一起。这不仅仅是阅读一大块慢得多。

The second effect is that, because four-byte data can only start at two places in an eight-byte chunk, it also ends inside that chunk. Consider what would happen if you tried to load four bytes of data that started at the sixth byte of an eight-byte chunk. The first two bytes are in the chunk, but the next two bytes are in the next chunk in memory. The processor would have to read two chunks from memory, take different bytes from each of them, and put those bytes together. That is much slower than just reading one chunk.

所以,存储器是由二的幂组织,因为这是比特的自然结果,和处理器需要对准,因为这使存储器访问效率更高。对齐自然是两个大国,这就是为什么你的结构尺寸的工作时,他们是被用于对准的两个大国的倍数更好。

So, memory is organized by powers of two because that is a natural result of bits, and processors require alignment because that makes memory access more efficient. The alignment is naturally powers of two, and that is why your structure sizes work better when they are multiples of the powers of two that are used for alignment.

这篇关于为什么填充必须是二的幂?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆