小議位元組對齊

2021-08-03 22:11:26 字數 2225 閱讀 6429

什麼是位元組對齊,為什麼要對齊

現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體位址訪問,這就需要各種型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。

作用和原因

各個硬體平台對儲存空間的處理上有很大的不同。一些平台對某些特定型別的資料只能從某些特定位址開始訪問。比如有些架構的cpu在訪問 乙個沒有進行對齊的變數的時候會發生錯誤,那麼在這種架構下程式設計必須保證位元組對齊.其他平台可能沒有這種情況,但是最常見的是如果不按照適合其平台要求對 資料存放進行對齊,會在訪問效率上帶來損失。比如有些平台每次讀都是從偶位址開始,如果乙個int型(假設為32位系統)如果存放在偶位址開始的地方,那 麼乙個讀週期就可以讀出這32bit,而如果存放在奇位址開始的地方,就需要2個讀週期,並對兩次讀出的結果的高低位元組進行拼湊才能得到該32bit數 據。

以下內容節選自《intel architecture 32 manual》:

字,雙字,和四字在自然邊界上不需要在記憶體中對齊。(對字,雙字,和四字來說,自然邊界分別是偶數字址,可以被4整除的位址,和可以被8整除的位址。)

無論如何,為了提高程式的效能,資料結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;然而,對齊的記憶體訪問僅需要一次訪問。

乙個字或雙字運算元跨越了4位元組邊界,或者乙個四字運算元跨越了8位元組邊界,被認為是未對齊的,從而需要兩次匯流排週期來訪問記憶體。乙個字起始位址是奇數但卻沒有跨越字邊界被認為是對齊的,能夠在乙個匯流排週期中被訪問。

某些操作雙四字的指令需要記憶體運算元在自然邊界上對齊。如果運算元沒有對齊,這些指令將會產生乙個通用保護異常(#gp)。雙四字的自然邊界是能夠被16 整除的位址。其他的操作雙四字的指令允許未對齊的訪問(不會產生通用保護異常),然而,需要額外的記憶體匯流排週期來訪問記憶體中未對齊的資料。

一次訪問時,要麼讀0x01~0x04,要麼讀0x05~0x08……

硬體不支援一次訪問就讀到0x02~0x05

舉個例子,如果0x02~0x05存了乙個int,讀取這個int就需要先讀0x01~0x04,留下0x02~0x04的內容,再讀0x05~0x08,留下0x05的內容,兩部分拼接起來才能得到那個int的值……

讀乙個int就要兩次記憶體訪問,效率就低了……

位元組對齊要區分四個概念

1、 基本資料型別的自身對齊值:

1位元組:char型

2位元組:short型

4位元組:int,float型別

8位元組:doublel型別

2、程式的指定對齊值:即#pragma pack(value)時的指定對齊值value

3、自定義型別的自身對齊值:結構體或類的成員中自身對齊值最大的值

4、自定義型別的有效對齊值:自定義型別的自身對齊值和指定對齊值中較小的值

據此,我們就可以很方便的來討論具體資料結構的成員和其自身的對齊方式。

#pragma pack(4)

struct test

char a;

short b;

char c;

上述結構體s的自身對齊值為2(b的自身對齊值),而指定對齊值為4(32位編譯器預設值),故最終的有效對齊值為2.

位域

位域是指資訊在儲存時,並不需要占用乙個完整的位元組, 而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態, 用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為「位域」或「位段」。所謂「位域」是把乙個位元組中的二進位劃分為幾 個不同的區域, 並說明每個區域的位數。每個域有乙個網域名稱,允許在程式中按網域名稱進行操作。 這樣就可以把幾個不同的物件用乙個位元組的二進位制位域來表示。

位域定義的幾點說明

對於位域的定義尚有以下幾點說明:

struct bs

在這個位域定義中,a佔第一位元組的4位,後4位填0表示不使用,b從第二位元組開始,占用4位,c占用4位。

2. 位域的長度不能大於指定型別固有長度,比如說int的位域長度不能超過32,bool的位域長度不能超過8。

3. 位域可以無位網域名稱,這時它只用來作填充或調整位置。無名的位域是不能使用的。例如:

struct k

;從以上分析可以看出,位域在本質上就是一種結構型別, 不過其成員是按二進位分配的。

小議LWIP 記憶體對齊

每一種處理器都會有自己的記憶體對齊要求,這樣做的目的很大程度上是為了處理器讀取記憶體資料的效率,當然還有匯流排等因素的影響,具體的可以看一下為什麼要記憶體對齊 data alignment straighten up and fly right 我覺得寫得還不錯。好了,廢話不多說,接下來看一下lwi...

位元組順序 位元組對齊

一.位元組順序的產生 在計算機中,資料是以位元組為單位存放的,而c語言中只有char才是乙個位元組,其他如int,float都是大於乙個位元組,所以就存在將資料按怎樣的順序存放的問題。一般有大端序和小端序兩種方式,特殊的還有混合序,也就是兩種存放方式同時存在於乙個計算機系統中。上面講的都是主機位元組...

位元組順序 位元組對齊

一.位元組順序的產生 在計算機中,資料是以位元組為單位存放的,而c語言中只有char才是乙個位元組,其他如int,float都是大於乙個位元組,所以就存在將資料按怎樣的順序存放的問題。一般有大端序和小端序兩種方式,特殊的還有混合序,也就是兩種存放方式同時存在於乙個計算機系統中。上面講的都是主機位元組...