董延華,黃 雨,李曉佳
(吉林師范大學(xué) 計算機(jī)學(xué)院,吉林 四平136000)
?
數(shù)據(jù)存儲邊界對齊問題研究
董延華,黃 雨,李曉佳
(吉林師范大學(xué) 計算機(jī)學(xué)院,吉林 四平136000)
該文針對數(shù)據(jù)在存儲過程中的邊界對齊問題,闡述了邊界對齊概念,提出了為什么邊界對齊及對齊等問題,解釋了計算機(jī)訪問內(nèi)存數(shù)據(jù)、編譯器進(jìn)行數(shù)據(jù)對齊等問題,對如何在程序設(shè)計過程中有效地使用邊界對齊方法,提高程序的運(yùn)行效率具有一定的理論指導(dǎo)與實用應(yīng)用價值.
邊界對齊;內(nèi)存對齊;編址
現(xiàn)代計算機(jī)中存儲空間是按照字節(jié)編址的,在32位系統(tǒng)環(huán)境下,字符型(char)變量為1字節(jié),整型(int)變量為4字節(jié),短整型(short)變量為2字節(jié),單精度型(float)變量為4字節(jié),雙精度型(double)為8字節(jié).[1]在如下代碼中:
typedef struct lizi1
{ char c1;
short s;
char c2;
int i;
}Bianjieduiqi;
假設(shè)內(nèi)存是緊湊排列的,如果c1的地址是0,s的地址就是1,c2的地址就是3,i的地址就是4.即:&c1=00000000,&s1=00000001,&c2=00000003,&i=00000004.但是通過實際的計算機(jī)程序輸出結(jié)果為:&c1=00000000,&s1=00000002,&c2=00000004,&i=00000008.程序的運(yùn)行結(jié)果與預(yù)期的不一致,這就是對齊邊界的問題.
邊界對齊(boundary alignment),即內(nèi)存對齊,是處理器為了提高處理性能而對存取數(shù)據(jù)的起始地址所提出的一種要求.
2.1 數(shù)據(jù)存儲方式
理論上講,程序中的模塊或者程序段連續(xù)的存取在內(nèi)存中,會大大提高內(nèi)存的訪問效率.但當(dāng)遇到程序轉(zhuǎn)移或隨機(jī)訪問少量數(shù)據(jù),訪問地址就不一定均勻地分布在多個存儲模塊之間,這樣就會產(chǎn)生存儲器沖突而降低了使用率.在如下定義中:
typedef struct lizi2
{ char a;
int b;
}type_t;
在采用邊界對齊的情況下,當(dāng)處理器需要訪問a變量和b變量時都只需進(jìn)行一次存取(一次存取操作為4字節(jié))如圖1所示.
圖1 采用邊界對齊的情況
若不采用邊界對齊,a變量只要一次處理器操作(一次存取操作為4字節(jié)),而b變量卻至少要進(jìn)行兩次操作.對于b變量,處理器還得調(diào)用更多指令將其合成一個完整的4字節(jié),這樣勢必大大降低了
程序效率.如圖2所示.
圖2 不采用邊界對齊的情況
數(shù)據(jù)的存儲所占空間因硬件平臺而定,不同的硬件平臺有不同的處理方式.
①對于一些特定類型的數(shù)據(jù),某些平臺會設(shè)定特定的地址進(jìn)行存取.
②有一些平臺在存取變量時,如果變量沒有被對齊就會發(fā)生錯誤.
③還有一些平臺對于不符合該平臺設(shè)定的對齊規(guī)則的數(shù)據(jù),存取時效率會降低損失.
一個int型數(shù)據(jù),其存儲的起始地址是偶數(shù)位置時,讀取數(shù)據(jù)只需要一個讀取周期,反之,如果起始地址存儲在奇數(shù)位置上,那么就需要兩個讀取周期.后者的讀取效率大大降低了.可見邊界對齊在數(shù)據(jù)存儲和讀取上起到了非常重要的作用.
2.2 邊界對齊的分類
(1)自然邊界對齊.自然邊界對齊(natural alignment)即默認(rèn)對齊方式,對齊長度等于size最大成員長度,按照size最大的成員對齊.
Struct這種結(jié)構(gòu)體是一種復(fù)合型數(shù)據(jù)類型,它是由基本數(shù)據(jù)類型和復(fù)合數(shù)據(jù)類型等數(shù)據(jù)單元構(gòu)成的.[2]在缺省的情況下,編譯器會自動為結(jié)構(gòu)體中的每一個成員按照自然對齊條件分配空間,以便提高效率.每一個成員都會存儲在它們被聲明的內(nèi)存順序中,整個結(jié)構(gòu)體的起始地址是由他的第一個變量的起始地址所決定.[3]例如:
struct lizi3
{char a;
short b;
char c;
};
根據(jù)以上程序short長度最大,占2字節(jié),因此a、c都以2字節(jié)對齊,結(jié)果為6;若改為:
struct lizi4
{char a;
int b;
char c;
};
其結(jié)果為12.
(2)指定邊界對齊.①在VC IDE中,修改:[Project]|[Settings],c/c++選項卡Category的Code Generation選項的Struct Member Alignment中修改,默認(rèn)是8字節(jié).②在編碼時,動態(tài)修改:#pragma pack ().
·使用#pragma pack (m),編譯器將對每一個變量按照m個字節(jié)進(jìn)行對齊;
·使用#pragma pack (),將指定字節(jié)對齊方式取消.[4]
#pragma pack (m)
struct lizi5
char a;
int b;
char c;
};
#pragma pack ()
當(dāng)m為4、8、16時,其對齊方式均一樣,lizi5的大小為12字節(jié).而當(dāng)m為2時,其發(fā)揮了作用,使得lizi5所占大小為8字節(jié).
3.1 邊界對齊對程序的影響
例如(32bit,x86環(huán)境,gcc編譯器):
struct A
{ int a;
char b;
short c;
};
struct B
{ char b;
int a;
short c;
};
輸出的結(jié)果是:A的大小為8字節(jié),B的大小為12字節(jié).
int型長度為4,char型長度為1,short型長度為2,結(jié)構(gòu)體A和結(jié)構(gòu)體B中都包括了int型,char型,short型各一個.那么我們可以推算出兩個結(jié)構(gòu)體的大小都應(yīng)該是7字節(jié).經(jīng)過測試得出,結(jié)構(gòu)體A的大小是8,結(jié)構(gòu)體B的大小是12,出現(xiàn)不同的值是因為編譯器自動對變量在空間上進(jìn)行對齊,但是我們可以改變這種默認(rèn)設(shè)置.
3.2 邊界對齊原則
編譯器在進(jìn)行邊界對齊時有四個基本要求:
①數(shù)據(jù)類型自身的對齊值:對于char數(shù)據(jù)類型,其長度為1字節(jié),short數(shù)據(jù)類型的長度是2字節(jié),int,float,double型長度為4個字節(jié).
②結(jié)構(gòu)體或者類的自身對齊值:成員中自身對齊值中最大的值.
③指定對齊值:#pragma pack (value)時的指定對齊值value.
④數(shù)據(jù)成員、結(jié)構(gòu)體和類的有效對齊值:自身對齊值和指定對齊值中最小的值.
3.3 編程中邊界對齊實際應(yīng)用
在編程中,有兩個方法能節(jié)約空間.第一種,首先我們假定結(jié)構(gòu)體的首地址為0,然后將結(jié)構(gòu)體中的各個變量根據(jù)類型由小到大聲明,極盡可能地減少中間的填補(bǔ)空間.第二種,顯式地插入reserved成員,以便用空間換取時間的效率,使其對齊.例如:
struct A
{char a;
char reserved[3];//使用空間換時間
int b;
}
reserved成員的使用可以達(dá)到提醒的作用,并不會對程序產(chǎn)生影響,不使用這個成員編譯器也會自然邊界對齊的.
本文介紹了邊界對齊這一概念,提供了邊界對齊在應(yīng)用時的使用方法,以及應(yīng)注意的問題,并給出了邊界對齊的具體應(yīng)用,有效地提高了數(shù)據(jù)的存取效率.對于程序而言,時間復(fù)雜度和空間復(fù)雜度是衡量程序好壞的標(biāo)準(zhǔn),而邊界對齊可以在一定程度上提高程序的運(yùn)行時間,從而深度優(yōu)化程序.
[1]王文龍.在c/c++數(shù)據(jù)存儲中使用字節(jié)對齊規(guī)則[J].喀什師范學(xué)院學(xué)報,2012,30(11).
[2]楊林.Borland C++程序遷移至現(xiàn)代集成開發(fā)環(huán)境的方法[J].電腦知識與技術(shù),2013(26).
[3]任慧,周振紅,張成才.混合計算工程中復(fù)合數(shù)據(jù)的傳遞(Ⅱ)——派生類型[J].武漢大學(xué)學(xué)報(工學(xué)版),2008,41(4).
[4]郭正慧,王巖.內(nèi)存對齊對網(wǎng)絡(luò)通信程序的影響[J].實驗室研究與探索,2010,29(5).
(責(zé)任編輯:王前)
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
林省發(fā)展計劃基金資助項目“基于吉林省公共計算平臺的高性能計算技術(shù)應(yīng)用研究”(20130101179JC,201105083);吉林省公共計算平臺基金資助項目“線性縮放并行亥姆霍茲和泊松方程算法及其在新型含能材料計算模擬設(shè)計中的應(yīng)用”(20130101179JC-17)
董延華,吉林扶余人,教授.
TP274
A
1008-7974(2016)05-0048-03
10.13877/j.cnki.cn22-1284.2016.10.016