CPU訪問位元組對齊

2021-06-05 16:16:46 字數 1929 閱讀 4388

編寫可移植**,需要考慮的乙個問題是如何訪問不對齊的資料。

例如, 如何讀取乙個儲存於乙個不是 4 位元組倍數的位址的4位元組值. i386 使用者常常訪問不對齊資料項, 但是不是所有的體系允許這個,很多現代的cpu體系會產生異常。

可以採用以下的函式,進行位元組對齊。

#include

get_unaligned(ptr);

put_unaligned(val, ptr);

這些巨集是無型別的, 並且用在每個資料項, 不管它是 1 個, 2 個, 4 個, 或者 8 個位元組長.

關於對齊的另乙個問題是跨平台的資料結構移植性. 同樣的資料結構可能在不同的平台上編譯方式不同,編譯器根據各個平台不同的慣例來安排結構成員對齊。

為了編寫可以跨不同cpu體系使用的資料結構,你應當一直強制自然的資料項對齊, 加上對乙個特定對齊方式的標準化. 自然對齊意味著儲存資料項在是資料項大小的整數倍的位址上(例如, 8-byte 項在 8 的整數倍的位址上)。

為了阻止編譯器以不希望的方式調整成員變數儲存位置,你應當使用填充成員來避免在資料結構中留下空洞。

為展示編譯器如何強制對齊, dataalign 程式在原始碼的 misc-progs 目錄中發布, 並且乙個對等的 kdataalign 模組是 misc-modules 的一部分. 這是程式在幾個平台上的輸出以及模組在 sparc64 的輸出:

arch align: char short int long ptr long-long u8 u16 u32 u64

i386 1 2 4 4 4 4 1 2 4 4

i686 1 2 4 4 4 4 1 2 4 4

alpha 1 2 4 8 8 8 1 2 4 8

armv4l 1 2 4 4 4 4 1 2 4 4

ia64 1 2 4 8 8 8 1 2 4 8

mips 1 2 4 4 4 8 1 2 4 8

ppc 1 2 4 4 4 8 1 2 4 8

sparc 1 2 4 4 4 8 1 2 4 8

sparc64 1 2 4 4 4 8 1 2 4 8

x86_64 1 2 4 8 8 8 1 2 4 8

kernel: arch align: char short int long ptr long-long u8 u16 u32 u64

kernel: sparc64 1 2 4 8 8 8 1 2 4 8

有趣的是注意不是所有的平台對齊 64-位值在 64-位邊界上, 因此你需要填充者成員來強制對齊和保證可移植性。

最後, 需要知道編譯器可能自己悄悄地插入填充成員到資料結構中,用來保證每個成員是對齊的。

為了目標處理器的良好效能. 自動填充可能妨礙你的企圖. 解決這個問題的方法是告訴編譯器這個結構必須是"緊湊的", 不能增加填充者。

例如, 核心標頭檔案 定義幾個與 x86 bios 介面的資料結構,定義如下:

struct

__attribute__ ((packed)) scsi;

在64-位cpu平台上編譯這個結構時,如果沒有使用__attribute__ ((packed)),在lun 成員前面,可能新增 2 個或者6 個位元組進行填充。

位元組對齊訪問

位元組對齊定義 指令對運算元起始位址有特定的要求 1 單位元組對齊 單位元組型別資料 可從任意位址取運算元 2 2位元組對齊 2位元組型別資料 希望從偶位址開始取運算元 3 4位元組對齊 4位元組型別資料 希望從能被 整除的位址開始取運算元 符合上面要求的 稱為對齊的儲存訪問 訪問結果正確 反之稱為...

mysql位元組對齊 位元組對齊會影響記憶體訪問的效率嗎

由於c 的專案做的少,又比較小,所以一直沒有注意位元組對齊的問題,但是,位元組對齊在大規模應用中對記憶體管理和cpu執行效率的影響應是挺大的。本文根據一些資料學習,做乙個小總結。cpu執行指令時從記憶體中獲取資料是按塊操作的,塊的大小可能為2 bytes,4 bytes,8 bytes,16 byt...

位元組順序 位元組對齊

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