45fan.com - 路饭网

搜索: 您的位置主页 > 网络频道 > 阅读资讯:内存对齐的影响因素有哪些?

内存对齐的影响因素有哪些?

2016-08-27 08:29:38 来源:www.45fan.com 【

内存对齐的影响因素有哪些?

) 为什么要有内存对齐

以下内容节选自《 Intel Architecture 32 Manual 》。

字,双字,和四字在自然边界上不需要在内存中对齐。(对字,双字,和四字来说,自然边界分别是偶数地址,可以被 4 整除的地址,和可以被 8 整除的地址。)

无论如何,为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。

一个字或双字操作数跨越了 4 字节边界,或者一个四字操作数跨越了 8 字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数但却没有跨越字边界被认为是对齐的,能够在一个总线周期中被访问。

某些操作双四字的指令需要内存操作数在自然边界上对齐。如果操作数没有对齐,这些指令将会产生一个通用保护异常( #GP )。双四字的自然边界是能够被 16 整除的地址。其他的操作双四字的指令允许未对齐的访问(不会产生通用保护异常),然而,需要额外的内存总线周期来访问内存中未对齐的数据。

) 常见数据类型的内存对齐

为了能使 CPU 对变量进行高效快速的访问,变量的起始地址应该具有某些特性,
即所谓的 对齐 。例如对于 4 字节的 int 类型变量,其起始地址应位于 4 字节边界上,
即起始地址能够被 4 整除。变量的对齐规则如下( 32 位系统):

Type

Alignment( 默认的自然对齐 )

char

在字节边界上对齐

short(16-bit)

在双字节边界上对齐

int long (32-bit)

4 字节边界上对齐

float

4 字节边界上对齐

double

8 字节边界上对齐

structures

单独考虑结构体的每个成员,它们在不同的字节边界上对齐。 其中最大的字节边界数就是该结构的字节边界数

 

structures

对于结构体 S1 的每个简单成员如果其对齐边界是 x1, 而它又含有结构体 S2, S2 内部的对齐边界是 x2, 则结构体 S1 的对齐边界取 X=max(x1, x2);

对于结构体 S2 中的某一成员 item ,它的对齐边界取 : X=max(sizeof(item)

 

范例:
struct s1{
short a;
long b;
};
struct s2{
char c;
s1 d;
long long e;
};



1.sizeof(s2) = ?
2.s2
的内存布局是怎么样的 ?

答:

//modify 2007.3.10

s1, 成员 a short, 2byte 自然对齐 ; 成员 b int, 4byte 自然对齐,取最大成员的 size(int), 因此这个结构体的对齐边界就是 4bytes. 所以 sizeof(s1)=8;

s2, 成员 c char, 1byte 自然对齐。但成员 d 则又是个结构体, sizeof(d) 8byte, 结构体 d 内成员的最大是 int, 它的内部对齐由 s1 可知,是按 4byte 对齐。那么这边又按什么对齐呢?下面成员 e long long, 默认按 8byte 对齐。因此 S1 中的成员是按 8BYTE 对齐 , S2 中仍然按照 4BYTE 对齐 .

a b
S1
的内存布局: 11**,1111, //4byte 对齐, sizeof(s1)=2+[2]+4 = 8

S2 的内存布局: 1***,****,11**,1111,11111111 //8byte 对齐, sizeof(s2)=1+[7]+8+8 = 24byte.

实际gcc下检测得到的是20byte=1+[3]+8+8, 估计是按4byte缺省对齐的。

说明:[ ]表示需要补位的值。Modify on Mar,5,2010.

------------------------------------------------------------------------------------

 

 

注意:
1 对于空结构体, sizeof == 1 ;因为必须保证结构体的每一个实例在内存中都
有独一无二的地址。
2 结构体的静态成员不对结构体的大小产生影响,因为静态变量的存储位置与
结构体的实例地址无关。

例如:
struct {static int I;} T; struct {char a; static int I;} T1;
sizeof(T) == 1; sizeof(T1) == 1;

 

) 各编译器下内存对齐的影响

上面那种是系统默认的对齐,也就是自然对齐。

现实中,编译器也能按指定的字节进行对齐,这称为指定对齐。如 VC gcc

--------------------------------MSDN VC----------------------------------------------------

使用伪指令 #pragma pack (n) ,编译器将按照 n 个字节对齐;
使用伪指令 #pragma pack () ,取消自定义字节对齐方式。

#pragma pack(n)

When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each structure member after the first is stored on the smaller member type or n-byte boundaries. If you use #pragma pack without an argument, structure members are packed to the value specified by /Zp. The default /Zp packing size is /Zp8.

----------------------------------GCC-----------------------------------------------

__attribute__ ((packed));


本文地址:http://www.45fan.com/a/question/68195.html
Tags: 内存 影响 因素
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部