数据存储边界对齐问题研究

2016-12-23 05:51董延华李晓佳
通化师范学院学报 2016年10期
关键词:编译器数据类型字节

董延华,黄 雨,李晓佳

(吉林师范大学 计算机学院,吉林 四平136000)



数据存储边界对齐问题研究

董延华,黄 雨,李晓佳

(吉林师范大学 计算机学院,吉林 四平136000)

该文针对数据在存储过程中的边界对齐问题,阐述了边界对齐概念,提出了为什么边界对齐及对齐等问题,解释了计算机访问内存数据、编译器进行数据对齐等问题,对如何在程序设计过程中有效地使用边界对齐方法,提高程序的运行效率具有一定的理论指导与实用应用价值.

边界对齐;内存对齐;编址

1 边界对齐的问题

现代计算机中存储空间是按照字节编址的,在32位系统环境下,字符型(char)变量为1字节,整型(int)变量为4字节,短整型(short)变量为2字节,单精度型(float)变量为4字节,双精度型(double)为8字节.[1]在如下代码中:

typedef struct lizi1

{ char c1;

short s;

char c2;

int i;

}Bianjieduiqi;

假设内存是紧凑排列的,如果c1的地址是0,s的地址就是1,c2的地址就是3,i的地址就是4.即:&c1=00000000,&s1=00000001,&c2=00000003,&i=00000004.但是通过实际的计算机程序输出结果为:&c1=00000000,&s1=00000002,&c2=00000004,&i=00000008.程序的运行结果与预期的不一致,这就是对齐边界的问题.

边界对齐(boundary alignment),即内存对齐,是处理器为了提高处理性能而对存取数据的起始地址所提出的一种要求.

2 边界对齐的作用

2.1 数据存储方式

理论上讲,程序中的模块或者程序段连续的存取在内存中,会大大提高内存的访问效率.但当遇到程序转移或随机访问少量数据,访问地址就不一定均匀地分布在多个存储模块之间,这样就会产生存储器冲突而降低了使用率.在如下定义中:

typedef struct lizi2

{ char a;

int b;

}type_t;

在采用边界对齐的情况下,当处理器需要访问a变量和b变量时都只需进行一次存取(一次存取操作为4字节)如图1所示.

图1 采用边界对齐的情况

若不采用边界对齐,a变量只要一次处理器操作(一次存取操作为4字节),而b变量却至少要进行两次操作.对于b变量,处理器还得调用更多指令将其合成一个完整的4字节,这样势必大大降低了

程序效率.如图2所示.

图2 不采用边界对齐的情况

数据的存储所占空间因硬件平台而定,不同的硬件平台有不同的处理方式.

①对于一些特定类型的数据,某些平台会设定特定的地址进行存取.

②有一些平台在存取变量时,如果变量没有被对齐就会发生错误.

③还有一些平台对于不符合该平台设定的对齐规则的数据,存取时效率会降低损失.

一个int型数据,其存储的起始地址是偶数位置时,读取数据只需要一个读取周期,反之,如果起始地址存储在奇数位置上,那么就需要两个读取周期.后者的读取效率大大降低了.可见边界对齐在数据存储和读取上起到了非常重要的作用.

2.2 边界对齐的分类

(1)自然边界对齐.自然边界对齐(natural alignment)即默认对齐方式,对齐长度等于size最大成员长度,按照size最大的成员对齐.

Struct这种结构体是一种复合型数据类型,它是由基本数据类型和复合数据类型等数据单元构成的.[2]在缺省的情况下,编译器会自动为结构体中的每一个成员按照自然对齐条件分配空间,以便提高效率.每一个成员都会存储在它们被声明的内存顺序中,整个结构体的起始地址是由他的第一个变量的起始地址所决定.[3]例如:

struct lizi3

{char a;

short b;

char c;

};

根据以上程序short长度最大,占2字节,因此a、c都以2字节对齐,结果为6;若改为:

struct lizi4

{char a;

int b;

char c;

};

其结果为12.

(2)指定边界对齐.①在VC IDE中,修改:[Project]|[Settings],c/c++选项卡Category的Code Generation选项的Struct Member Alignment中修改,默认是8字节.②在编码时,动态修改:#pragma pack ().

·使用#pragma pack (m),编译器将对每一个变量按照m个字节进行对齐;

·使用#pragma pack (),将指定字节对齐方式取消.[4]

#pragma pack (m)

struct lizi5

char a;

int b;

char c;

};

#pragma pack ()

当m为4、8、16时,其对齐方式均一样,lizi5的大小为12字节.而当m为2时,其发挥了作用,使得lizi5所占大小为8字节.

3 边界对齐的应用

3.1 边界对齐对程序的影响

例如(32bit,x86环境,gcc编译器):

struct A

{ int a;

char b;

short c;

};

struct B

{ char b;

int a;

short c;

};

输出的结果是:A的大小为8字节,B的大小为12字节.

int型长度为4,char型长度为1,short型长度为2,结构体A和结构体B中都包括了int型,char型,short型各一个.那么我们可以推算出两个结构体的大小都应该是7字节.经过测试得出,结构体A的大小是8,结构体B的大小是12,出现不同的值是因为编译器自动对变量在空间上进行对齐,但是我们可以改变这种默认设置.

3.2 边界对齐原则

编译器在进行边界对齐时有四个基本要求:

①数据类型自身的对齐值:对于char数据类型,其长度为1字节,short数据类型的长度是2字节,int,float,double型长度为4个字节.

②结构体或者类的自身对齐值:成员中自身对齐值中最大的值.

③指定对齐值:#pragma pack (value)时的指定对齐值value.

④数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中最小的值.

3.3 编程中边界对齐实际应用

在编程中,有两个方法能节约空间.第一种,首先我们假定结构体的首地址为0,然后将结构体中的各个变量根据类型由小到大声明,极尽可能地减少中间的填补空间.第二种,显式地插入reserved成员,以便用空间换取时间的效率,使其对齐.例如:

struct A

{char a;

char reserved[3];//使用空间换时间

int b;

}

reserved成员的使用可以达到提醒的作用,并不会对程序产生影响,不使用这个成员编译器也会自然边界对齐的.

4 结束语

本文介绍了边界对齐这一概念,提供了边界对齐在应用时的使用方法,以及应注意的问题,并给出了边界对齐的具体应用,有效地提高了数据的存取效率.对于程序而言,时间复杂度和空间复杂度是衡量程序好坏的标准,而边界对齐可以在一定程度上提高程序的运行时间,从而深度优化程序.

[1]王文龙.在c/c++数据存储中使用字节对齐规则[J].喀什师范学院学报,2012,30(11).

[2]杨林.Borland C++程序迁移至现代集成开发环境的方法[J].电脑知识与技术,2013(26).

[3]任慧,周振红,张成才.混合计算工程中复合数据的传递(Ⅱ)——派生类型[J].武汉大学学报(工学版),2008,41(4).

[4]郭正慧,王岩.内存对齐对网络通信程序的影响[J].实验室研究与探索,2010,29(5).

(责任编辑:王前)

Research on Data Storage Boundary Alignment Problem

DONG Yan-hua,HUANG Yu,LI Xiao-jia

(CollegeofComputer,JilinNormalUniversity,Siping,Jilin136000,China)

In view of the process of storage boundary alignment problem,the concepts of boundary alignment is clarified,and the computer acess to memory data and the compliler for data alignment is explained. It is meaningful for using boundary alignment in the process of program design methods effectively and improving the efficiency of the program.It provides a certain theoretical guidance and practical application value.

boundary alignment;Memory alignment;addressing

2015-11-08

林省发展计划基金资助项目“基于吉林省公共计算平台的高性能计算技术应用研究”(20130101179JC,201105083);吉林省公共计算平台基金资助项目“线性缩放并行亥姆霍兹和泊松方程算法及其在新型含能材料计算模拟设计中的应用”(20130101179JC-17)

董延华,吉林扶余人,教授.

TP274

A

1008-7974(2016)05-0048-03

10.13877/j.cnki.cn22-1284.2016.10.016

猜你喜欢
编译器数据类型字节
No.8 字节跳动将推出独立出口电商APP
如何理解数据结构中的抽象数据类型
基于相异编译器的安全计算机平台交叉编译环境设计
运行速度大突破华为《方舟编译器》详解
No.10 “字节跳动手机”要来了?
基于MSP430的四旋翼飞行器的S-BUS通信协议的设计与实现
基于SeisBase模型的地震勘探成果数据管理系统设计
线上众筹产品的特征分析与研究
相似度计算及其在数据挖掘中的应用
通用NC代码编译器的设计与实现