查看積分策略說明發表回覆
Discuz! 代碼
提示插入
直接插入
說明訊息

插入粗體文本 插入斜體文本 插入下劃線 置中對齊 插入超級連結 插入信件位址 插入圖像 插入 flash 插入代碼 插入引言 插入列表
刪除線 直線分隔線 虛線分隔線
    
添加文字底框
內容 [字數檢查]:

表情符號

更多 Smilies
字型大小 |||
溫馨提示:本區開放遊客瀏覽。


文章關鍵字 : [功能說明]
(關鍵字可加強搜索準確性, 如關鍵字多於一組, 請以 , 作分隔, e.g. : 阿笨,shiuh,第一笨)

 關閉 URL 識別 | html 禁用
 關閉 表情符號 | 表情符號 可用
 關閉 Discuz! 代碼 | Discuz! 代碼 可用
使用個人簽名
接收新回覆信件通知
推薦放檔網絡空間

檔案(Torent, zip等)
  1. freedl
  2. multiupload
  3. btghost
  4. 便當狗
  5. mediafire
  6. pillowangel
圖片(JPG, GIF等)
  1. hotimg
  2. tinypic
  3. mousems2
  4. imageshack
  5. imm.io
>>>歡迎推薦好用空間


最新10篇文章回顧
Acute

 發表於 2008-12-7 02:27 PM

alignment 其實不僅僅發生在structure, 只是structure 內的alignment 比較會引起注意!
如同dayi 所說, 這跟CPU/OS/Compiler 息息有關

笨阿呆... 小神童C 語言比較當中, 應該就有這一段, 你白看嚕!

alignment 最主要來自CPU(硬體)的先天限制, 大家都習慣Intel 的x86 CPU, 所以對alignment 就相對觀念模糊, 如果從硬體的角度去觀看這件事情, 或許相對簡單很多.

當CPU 是32 bits, 代表CPU 每次存取記憶體, 就是一次處理32 bits, 站在讓CPU 發揮最大效能的角度上, 每次記憶體的讀取/改變/寫入, 當然是使用32bits 處理, 當你企圖變更非32 bits 的資料, 例如你改變byte 1/2, CPU 必須很費事的, 先讀取32 bits 資料, 變更bit [8..23] & 保留bit[0..7, 24..31], 然後把32 bits 資料寫回去!!

Intel CPU 因為從8088/8086.. 一路到現在, 為了跟以前相容, 所以始終容許你在非CPU bus 容量的邊界條件上恣意存取記憶體, 但是, 相對讓CPU 效能大打折扣, 如上面所說的, 你的一個簡單寫入動作, 硬體其實是做了:讀取, 遮罩變更, 寫入三個動作!!! 很多沒有歷史包袱的CPU 是不容許這樣玩耍的!! 那.. 如果CPU 不容許.. OS/Compiler 能搞啥? 呵, 當然, CPU 不容許, 意味著, 當程式這樣蠻幹, 硬體例外事件(Exception)就會被觸發, 所以, OS 有機會改變這項不容許變成容許, 只是, 成本就更高了, 當你存取bit [8..23], 硬體產生例外處理, 然後OS 接手, 用一長串的程式碼去完成你要的16 bits 存取   延續上面的例子, 更複雜的現象就是你讀取/存入byte3/4, 當讀取時, CPU bus 要讀取兩次資料, 然後組合成你要的16 bits 資料給你, 當你寫入, 就需要讀取-變更-寫入進行兩個cycle

x86 上的compiler 為了解決上述問題, 所以, 就有alignment 設定出現, 也是為了跟過往相容, 當你的程式沒有任何包袱存在, 要跑32 bits platform, 最好就是32 bits alignment, 但是如果有包袱, 例如上面阿呆列的那個Windows BMP header, 就得乖乖設定成16 bits alignment !!

再換另一個角度去思考這個問題, 如果CPU 不支援非alignment 上的存取, OS 又不support 呢?
那就是乖乖寫程式處理, 所以, 當你看網路上很多open source 的程式碼, 有時會看到, 很多資料從硬碟內讀取進來, 都不是直接使用對應structure, 而是讀到一個記憶體區塊, 然後才逐步把資料一項一項填寫入structure 內, 不要以為寫程式的人發神經, 其實那才是一個最正確的程式寫法, 這可以確保, 程式不管移植到任何CPU/OS platform, 他都保證正確執行的方法!!! 通常這類程式, 你能看到的不僅僅是alignment 問題, 還包括endian 問題

Acute.


dayi

 發表於 2008-7-12 02:27 PM

不同的CPU/OS/compiler會造成不同的結果
但相同的是都會做structure alignment的動作
所以structure裡就會有padding

對以下兩個struct做sizeof()

struct StructA
{
    char a;
    char b;
    int c;
};

struct StructB
{
    char a;
    int c;
    char b;
};
雖然這兩個裡面存放的都是2組char,1組int
但會發現sizeof()的結果卻是不同的


Pika123

 發表於 2008-7-12 01:51 PM

自己來解答~
原來short會被放在記憶體位址是2的倍數上
int會放在4的倍數上...
難怪= =....


Pika123

 發表於 2008-7-12 01:39 PM

最近在研究讀取BMP的Header
所以用到以下的structure

typedef struct BITMAPFILEHEADER {
    unsigned short bfType;
    unsigned int   bfSize;
    unsigned short bfReserved1;
    unsigned short bfReserved2;
    unsigned int   bfOffBits;
} BITMAPFILEHEADER;
不過為什麼 sizeof( BITMAPFILEHEADER ) 會是 16 !!?
不是應該是14嘛@@?
不知道有沒有人能以比較淺顯的方式說明一下

以上

[Pika123 在  2008-7-12 01:51 PM 作了最後編輯]





所在時區為 GMT+8, 現在時間是 2024-4-27 02:55 PM
清除 Cookies - 連絡我們 - TWed2k © 2001-2046 - 純文字版 - 說明
Discuz! 0.1 | Processed in 0.015339 second(s), 7 queries , Qzip disabled