也談字節對齊帶來效率的差異

因爲今天和同事談到了ARM平臺下數據總線寬度及對齊方式對程序效率的影響問題
在定義結構數據類型時,爲了提高系統效率,要注意字長對齊原則。
正好有點感觸給大家談談 本人水平有限的很有什麼問題請朋友指正:
本文主要給大家解釋下所謂的對齊到底是什麼?怎麼對齊?爲什麼會對齊或者說對齊帶來什麼樣的效率差異?

1.
先看下面的例子:
#include <iostream.h>
#pragma pack(4)
struct A
{
 char a;
 int  b;
};
#pragma pack()

#pragma pack(1)
struct B
{
 char a;
 int  b;
};
#pragma pack()

int main()
{
 
 A a;
 cout<<sizeof(a);   //8
 
 B b;
 cout<<sizeof(b);   //5
}

默認的vc我記得是4字節對齊ADS下是一字節對齊
因爲是c/c++社區大家對PC比較熟悉 我就談PC下的對齊
PC下設計放的太長時間的有錯誤就別客氣直接說

大家可以看到在ms的vc下按4字節對齊和1字節對齊的結果是截然不同的分別爲8和5
爲什麼會有這樣的結果呢?這就是x86上字節對齊的作用。爲了加快程序執行的速度,
一些體系結構以對齊的方式設計,通常以字長作爲對齊邊界。對於一些結構體變量,
整個結構要對齊在內部成員變量最大的對齊邊界,如A,整個結構以4爲對齊邊界,所以sizeof(a)爲8,而不是5。
如果是原始我們概念下的的A中的成員將會一個挨一個存儲 應該只有char+int只有5個字節
這個差異就是由於對齊導致的
顯然我們可以看到 A的對齊要比B浪費3個字節的存儲空間
那爲什麼還要採取對齊呢?
那是因爲體系結構的對齊和不對齊,是在時間和空間上的一個權衡。
字節對齊節省了時間。應該是設計者考慮用空間換取時間。
爲什麼說對齊會提高效率呢節省時間?我想大家要理解的重點之重點就在這裏了
在我們常用的PC下總線寬度是32位
1.如果是總線寬度對齊的話
那麼所有讀寫操作都是獲取一個<=32位數據可以一次保證在數據總線傳輸完畢
沒有任何的額外消耗
|1|2|3|4|5|6|7|8|
從1開始這裏是a的起始位置,5起始爲b的位置 訪問的時候
如果訪問a一次在總線傳輸8位其他24位無效的
訪問b時則一次在總線上傳輸32完成
讀寫均是一次完整
插敘一下 讀操作先要將讀地址放到地址總線上然後下個時鐘週期再從外部
存儲器接口上讀回數據通過數據總線返回需要兩個週期
而寫操作一次將地址及數據寫入相應總線就完成了
讀操作要比寫操作慢一半
 
2.我們看訪問數據時如果不對齊地址的情況
|1|2|3|4|5|6|7|8|
此時a的地址沒變還在1而因爲是不對齊則b的位置就在2處
這時訪問就帶來效率上問題 訪問a時沒問題還是讀會一個字節
但是2處地址因爲不是總線寬度對齊一般的CPU在此地址操作將產生error
如sparc,MIPS。它們在硬件的設計上就強制性的要求對齊。在不對齊的地址上肯定發生錯誤
但是x86是支持非對齊訪問的
它通過多次訪問來拼接得到的結果,具體做法就是從1地址處先讀回後三字節234 暫存起來
然後再由5地址處讀回一個字節5 與234進行拼接組成一個完整的int也就是b返回
大家看看如此的操作帶來的消耗多了不止三倍很明顯在字長對齊時效率要高許多
淡然這種效率僅僅是訪問多字節帶來的 如果還是進行的byte操作那效率差不了多少


目前的開發普遍比較重視性能,所以對齊的問題,有2種不同的處理方法:
1)    有一種使用空間換時間做法是顯式的插入reserved成員:
         struct A{
           char a;
           char reserved1[3];  //使用空間換時間
           int b;
           
}a;
2)    隨便怎麼寫,一切交給編譯器自動對齊。
還有一種將邏輯相關的數據放在一起定義

代碼中關於對齊的隱患,很多是隱式的。比如在強制類型轉換的時候。下面舉個例子:
unsigned int i = 0x12345678;
unsigned char *p=NULL;
unsigned short *p1=NULL;

p=&i;
*p=0x00;
p1=(unsigned short *)(p+1);
*p1=0x0000;
最後兩句代碼,從奇數邊界去訪問unsignedshort型變量,顯然不符合對齊的規定。
在x86上,類似的操作只會影響效率,但是在MIPS或者sparc上,可能就是一個error

發佈了53 篇原創文章 · 獲贊 1 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章