藍森林首頁 | 返回主頁 | 本站地圖 | 站內搜索 | 聯繫信箱 |
 您目前的位置:首頁 > 自由軟件 > 技術交流 > 應用編程


    

藍森林 http://www.lslnet.com 2006年6月6日 10:18


內存對齊的概念.

內存對齊比較精確的定義:一個數據類型只允許存放在該數據類型整數倍的內存位置上;內存對齊通常是一些硬件系統的硬性要求;

          例子:
#include <stdio.h>;

int main(void)
{
        char    *str = NULL;
        short int       *test1 = NULL;
        int             *test2 = NULL;

        str = (char *)malloc(100);
        if(str == NULL){
                printf("malloc error\n");
                exit(1);
        }

        printf("the str addr is %x\n", str);
        printf("the str+2 addr is %x\n", str+2);

        test1 = (short int *)(str + 2);
        *test1 = 1;

        printf("step1 pass\n");

        test2 = (int *)(str + 2);
        *test2 = 1;

        printf("step2 pass\n");

        return  0;
}

在sparc上運行結果為:
the str addr is 20ca0
the str+2 addr is 20ca2
step1 pass
總線錯誤 (core dumped)

而在intel上運行沒有任何問題;

上述程序,*test1是short int型,長度是2字節,它所放的內存位置str+2是2的整數倍,沒問題;而*test2是int型,長度是4字節,它所放的內存位置str+2不是4的整數倍,因此會總線錯誤 (core dumped)

因此可以看出,在sparc上有內存對齊的要求,大家編程時要注意這一點!

不對請更正!

內存對齊的概念.

我覺得這樣理解可能不正確

因為對齊只是編譯器為了內存訪問性能更高所做的優化
另外你也可以選擇不對齊
有對應編譯選項

可以看頂上FAQ查找pcak說明

在網絡包中pack(1)更是重要
因為不同的CPU體系結構不一樣

另外每個平台編譯器優化對齊數也不一樣
所以在這種時候一般會使用pack(1)對齊

內存對齊的概念.

樓上,不知道你在sparc上運行過上述程序沒有,保證你出core;

另外,編譯器對齊確實可以提供內存訪問速度,但是這裡的編譯器對齊只是針對struct,而對於c語言裡的原始類型,如 int,short int等必須放在該數據類型整數倍的位置上,如果不這樣做,你的程序就會core掉;

內存對齊的概念.

某些RISC對此有硬性要求,不只是數據,指令代碼都要求。對CISC以及其他RISC,大多是為了提升性能。

內存對齊的概念.

那如果一個struct

struct{
char a;
int b;
char c;
int d;
}
使用pack(1)後訪問的話呢  
使用pack(1)後它們都是連接保存的

我沒有solaris條件

但是在網絡包中對結構都使用pack(1) 收發
所以覺得這不是問題

同樣那個程序也沒有辦法測試
如果有條件的話可以知道是什麼問題的

內存對齊的概念.

在某些系統上,如sparc,你的結構在訪問int b時可能就會core。不過這個問題也與編譯器的處理有關,有些編譯器會對非對齊的數據特殊處理,保證不產生core。
至於網絡包發送,因為面對的都是字節,沒有對結構成員的訪問,所以不存在問題。此外,結構直接傳送是不鼓勵的,會有不兼容的問題出現,包括字長、字節序等,即使你用了pack(1)也是不行的。所以,在網絡編程時沒有必要用pack(1)。
習慣了C編程的程序員總是希望不用進行編解碼就可以很好地進行網絡通信,其實完全是不對的。不要對對端做太多假設,這樣你的應用才有更好的可移植性。相對與網絡傳輸的性能而言,編解碼的開銷根本不算什麼。

內存對齊的概念.

-->     

無雙,你知道你的這個結構體在用pack(1)後,在訪問結構體成員b時,它是要訪問兩次的,然後把這兩次訪問的結果和並起來,這樣才是b成員的數據;

內存對齊的概念.

-->     


對齊的原因不是節省帶寬
我想在這點上你是理解錯了

有的系統對結構使用不同的對齊方式如8字節對齊 並且還有大印第安小印弟安區別

所以如果在不同操作系統上發送的包
那麼其它系統會不能理解你包的內容
因此需要對1位對齊

這點可以看頂上FAQ中討論 裡面有solaris linux windows平台上各編譯器選項的討論

還有就是傳送的時間不訪問
但收到的一方是訪問的
直接訪問那個結構 直接按1字節對齊的方式訪問
所以在多數網絡操作系統中 沒有限制某個變量一定要從哪裡開始保存
只是性能上有差異

內存對齊的概念.

你的這些問題我前面的帖子裡都說了,而且強調了即使pack(1)在異構網絡環境中也是有問題的。我說編解碼的開銷相比網絡傳輸的性能根本不算什麼,並不是說帶寬的問題,而是指你的應用的性能問題(增加編解碼功能對網絡應用的影響很小)。像你說的「大印第安小印弟安區別」(我的帖子裡說的是字節序。目前的硬件體系還沒有位序問題,這也是值得慶幸的),直接的結構傳送是無法避免的,所以不能用結構傳送,即使是pack(1)。
所以,系統的對齊方式對網絡通信本來是不該有影響的,重要的仍然是字長、字節序這些問題。

內存對齊的概念.

老大
那你先開發一個linux和windows通信的網絡程序後再說

做和solaris的更好



Copyright © 1999-2000 LSLNET.COM. All rights reserved. 藍森林網站 版權所有。 E-mail : webmaster@lslnet.com