真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

為什么存在內(nèi)存對(duì)齊

  說(shuō)到內(nèi)存對(duì)齊,很多人都知道是怎么回事。但是內(nèi)存對(duì)齊該娘不是本文的重點(diǎn),本文的重點(diǎn)是內(nèi)存對(duì)齊有什么好處。
  CPU訪問(wèn)某個(gè)數(shù)據(jù)時(shí),要求其存儲(chǔ)地址必須是相應(yīng)數(shù)據(jù)類型的自然邊界。對(duì)于存儲(chǔ)地址不在其相應(yīng)類型自然邊界的數(shù)據(jù),不支持非對(duì)齊數(shù)據(jù)訪問(wèn)的CPU,會(huì)導(dǎo)致CPU異常;即使是支持非對(duì)齊數(shù)據(jù)訪問(wèn)的CPU,也會(huì)嚴(yán)重影響程序效率。
   假設(shè)非對(duì)齊訪問(wèn)出現(xiàn)在位于操作系統(tǒng)之上的進(jìn)程,且CPU不支持非對(duì)齊數(shù)據(jù)訪問(wèn),那么對(duì)于出現(xiàn)CPU異常的情況,可能操作系統(tǒng)會(huì)對(duì)其進(jìn)行處理,(1)將所需要的數(shù)據(jù)裝載,并返回,或者說(shuō)(2)直接讓進(jìn)程死掉。情形(2)不需要多做解釋;對(duì)情況(1)來(lái)說(shuō),非對(duì)齊訪問(wèn)每次都要進(jìn)入異常處理程序,相比于一條指令直接拿到數(shù)據(jù),效率極其低下。
  假設(shè)非對(duì)齊訪問(wèn)出現(xiàn)在直接位于硬件之上的進(jìn)程,且CPU不支持非對(duì)齊數(shù)據(jù)訪問(wèn),那么對(duì)于出現(xiàn)CPU異常的情況來(lái)說(shuō),基本上的直觀反應(yīng)是進(jìn)程退出并出現(xiàn)堆棧信息。 

成都創(chuàng)新互聯(lián)長(zhǎng)期為上千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為歷下企業(yè)提供專業(yè)的網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)歷下網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。

 現(xiàn)在假設(shè)有一個(gè)8字節(jié)數(shù)據(jù)如下,|表示數(shù)據(jù)開(kāi)始位置,|-|表示自然邊界

 |-|BBBBB|BBB|-|BBBBB|BBB

    其前三字節(jié)為前一個(gè)對(duì)齊的八字節(jié)數(shù)據(jù)的后三字節(jié),其后五字節(jié)為后一個(gè)對(duì)齊的八字節(jié)數(shù)據(jù)的前五字

 對(duì)于不支持非對(duì)齊裝載指令的CPU來(lái)說(shuō),要裝載這樣的一個(gè)數(shù)據(jù),需要先裝載前一個(gè)八字節(jié)數(shù)據(jù),再裝載后一個(gè)八字節(jié)數(shù)據(jù),然后將前一個(gè)八字節(jié)數(shù)據(jù)的后三字節(jié)與后一個(gè)八字節(jié)數(shù)據(jù)的前五字節(jié)數(shù)據(jù)合并才能得到結(jié)果,與對(duì)齊數(shù)據(jù)的訪問(wèn)相比,多了一個(gè)裝載指令以及相關(guān)合并指令的開(kāi)銷,一般來(lái)說(shuō),在忽視緩存未命中的情況下,裝載指令的執(zhí)行與得到結(jié)果之間是存在額外開(kāi)銷的,因此這個(gè)差別是很大的,何況上邊說(shuō)的,假設(shè)是在操作系統(tǒng)對(duì)CPU異常進(jìn)行處理時(shí)為其加載數(shù)據(jù),那么異常處理程序的開(kāi)銷可能更大;對(duì)非對(duì)齊數(shù)據(jù)的寫(xiě)入時(shí)也需要額外的加載,合并操作。

即使對(duì)于支持非對(duì)齊數(shù)據(jù)加載的CPU,依然會(huì)極大的影響效率,差別只是它省略掉了CPU異常處理過(guò)程。

 再進(jìn)一層,假設(shè)之前描述的非對(duì)齊數(shù)據(jù)剛好橫跨兩個(gè)cache line,而且這兩個(gè)cache line至少有一個(gè)不在cache中(雖然對(duì)齊數(shù)據(jù)也會(huì)存在未命中,但是與非對(duì)齊相比,它不會(huì)橫跨兩個(gè)cache line),那么這個(gè)訪問(wèn)效率絕對(duì)不是多幾十條指令的問(wèn)題了。

 因此,內(nèi)存不對(duì)齊的壞處不是浪費(fèi)內(nèi)存,因?yàn)榧词刮覍?xiě)一個(gè)隨便在不同位置放置不同大小的數(shù)據(jù)結(jié)構(gòu)時(shí),只要告訴編譯器說(shuō)必須按照一字節(jié)對(duì)齊,編譯器編譯時(shí)肯定按照我的意愿不浪費(fèi)一個(gè)字節(jié)的內(nèi)存。編譯器默認(rèn)按照自然邊界對(duì)齊,是因?yàn)樗笮剩WC程序的正常運(yùn)行(因?yàn)榉菍?duì)齊訪問(wèn)可能導(dǎo)致進(jìn)程退出)。我們對(duì)結(jié)構(gòu)體的組織的調(diào)整是為了節(jié)約內(nèi)存,而調(diào)整的規(guī)則就是按照內(nèi)存對(duì)齊來(lái)安插數(shù)據(jù)。

每個(gè)特定平臺(tái)上的編譯器都有自己的默認(rèn)“對(duì)齊系數(shù)”(也叫對(duì)齊模數(shù))。程序員可以通過(guò)預(yù)編譯命令#pragma pack(n),n=1,2,4,8,16來(lái)改變這一系數(shù),其中的n就是你要指定的“對(duì)齊系數(shù)”。

規(guī)則:

1、數(shù)據(jù)成員對(duì)齊規(guī)則:結(jié)構(gòu)(struct)(或聯(lián)合(union))的數(shù)據(jù)成員,第一個(gè)數(shù)據(jù)成員放在offset為0的地方,以后每個(gè)數(shù)據(jù)成員的對(duì)齊按照#pragma pack指定的數(shù)值和這個(gè)數(shù)據(jù)成員自身長(zhǎng)度中,比較小的那個(gè)進(jìn)行。

2、結(jié)構(gòu)(或聯(lián)合)的整體對(duì)齊規(guī)則:在數(shù)據(jù)成員完成各自對(duì)齊之后,結(jié)構(gòu)(或聯(lián)合)本身也要進(jìn)行對(duì)齊,對(duì)齊將按照#pragma pack指定的數(shù)值和結(jié)構(gòu)(或聯(lián)合)最大數(shù)據(jù)成員長(zhǎng)度中,比較小的那個(gè)進(jìn)行。

3、結(jié)合1、2可推斷:當(dāng)#pragma pack的n值等于或超過(guò)所有數(shù)據(jù)成員長(zhǎng)度的時(shí)候,這個(gè)n值的大小將不產(chǎn)生任何效果。

Win32平臺(tái)下的微軟C編譯器的對(duì)齊策略:

1)結(jié)構(gòu)體變量的首地址是其最長(zhǎng)基本類型成員的整數(shù)倍;

備注:編譯器在給結(jié)構(gòu)體開(kāi)辟空間時(shí),首先找到結(jié)構(gòu)體中最寬的基本數(shù)據(jù)類型,然后尋找內(nèi)存地址能是該基本數(shù)據(jù)類型的整倍的位置,作為結(jié)構(gòu)體的首地址。將這個(gè)最寬的基本數(shù)據(jù)類型的大小作為上面介紹的對(duì)齊模數(shù)。

2)結(jié)構(gòu)體每個(gè)成員相對(duì)于結(jié)構(gòu)體首地址的偏移量(offset)都是成員大小的整數(shù)倍,如有需要編譯器會(huì)在成員之間加上填充字節(jié)(internal adding);

備注:為結(jié)構(gòu)體的一個(gè)成員開(kāi)辟空間之前,編譯器首先檢查預(yù)開(kāi)辟空間的首地址相對(duì)于結(jié)構(gòu)體首地址的偏移是否是本成員的整數(shù)倍,若是,則存放本成員,反之,則在本成員和上一個(gè)成員之間填充一定的字節(jié),以達(dá)到整數(shù)倍的要求,也就是將預(yù)開(kāi)辟空間的首地址后移幾個(gè)字節(jié)。

3)結(jié)構(gòu)體的總大小為結(jié)構(gòu)體最寬基本類型成員大小的整數(shù)倍,如有需要,編譯器會(huì)在最末一個(gè)成員之后加上填充字節(jié)。

備注:

a、結(jié)構(gòu)體總大小是包括填充字節(jié),最后一個(gè)成員滿足上面兩條以外,還必須滿足第三條,否則就必須在最后填充幾個(gè)字節(jié)以達(dá)到本條要求。

b、如果結(jié)構(gòu)體內(nèi)存在長(zhǎng)度大于處理器位數(shù)的元素,那么就以處理器的倍數(shù)為對(duì)齊單位;否則,如果結(jié)構(gòu)體內(nèi)的元素的長(zhǎng)度都小于處理器的倍數(shù)的時(shí)候,便以結(jié)構(gòu)體里面最長(zhǎng)的數(shù)據(jù)元素為對(duì)齊單位。

4) 結(jié)構(gòu)體內(nèi)類型相同的連續(xù)元素將在連續(xù)的空間內(nèi),和數(shù)組一樣。

總結(jié):

1、平臺(tái)原因(移植原因):不是所有的硬件平臺(tái)都能訪問(wèn)任意地址上的任意數(shù)據(jù)的;某些硬件平臺(tái)只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。

2、性能原因:數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對(duì)齊。原因在于,為了訪問(wèn)未對(duì)齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問(wèn);而對(duì)齊的內(nèi)存訪問(wèn)僅需要一次訪問(wèn)。


當(dāng)前題目:為什么存在內(nèi)存對(duì)齊
分享路徑:http://weahome.cn/article/goghse.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部