閱讀《游戲引擎架構(gòu)》(四)

對(duì)象的內(nèi)存布局

在class和struct中,編譯器不會(huì)把數(shù)據(jù)程序員緊湊的包裹在一起,因?yàn)槊糠N數(shù)據(jù)都有其天然的對(duì)齊方式,供CPU高效的從內(nèi)存讀/寫(xiě)。對(duì)齊方式即內(nèi)存地址為對(duì)齊字節(jié)大小的倍數(shù),另外編譯器可能會(huì)為了數(shù)組的對(duì)齊,會(huì)在末端加入填充,以下是32位系統(tǒng)下各個(gè)類(lèi)型的大小(單位:字節(jié)):
int:4字節(jié);float:4字節(jié);double:8字節(jié);bool:1字節(jié);char:1字節(jié);short:2字節(jié);long:4字節(jié)或者8字節(jié)

例如下圖:

struct InefficientPacking
{
  U32   mU1;    //32位
  F32   mF2;    //32位
  U8    mB3;    //8位
  I32   mI4;    //32位
  bool  mB5;    //8位
  char* mP6;    //32位
};
混合數(shù)據(jù)成員大小導(dǎo)致低效的struct包裹

現(xiàn)在,我們重新考慮上圖的中struct InefficientPacking布局里的空隙。在class或struct中,當(dāng)把較小的數(shù)據(jù)類(lèi)型(如8位的bool)放置于較大類(lèi)型(如32位的float)之間,編譯器會(huì)加入填充(空隙),以保證所有成員都是正常地對(duì)齊的。當(dāng)聲明數(shù)據(jù)結(jié)構(gòu)時(shí),認(rèn)真對(duì)待對(duì)齊和包裹是個(gè)好習(xí)慣。如以下代碼及圖所示,只需簡(jiǎn)單地重新排列上述例子中的成員,就能省去了一些浪費(fèi)了的填充空間。

struct MoreEfficientPacking
{
  U32   mU1;    //32位(4字節(jié)對(duì)齊)
  F32   mF2;    //32位(4字節(jié)對(duì)齊)
  I32   mI4;    //32位(4字節(jié)對(duì)齊)
  char* mP6;    //32位(4字節(jié)對(duì)齊)
  U8    mB3;    //8位(1字節(jié)對(duì)齊)
  bool  mB5;    //8位(1字節(jié)對(duì)齊)
};
小成員組合在一起,包裹更高效

在內(nèi)存布局上,C++的類(lèi)有別于C的結(jié)構(gòu)之處有二——繼承與虛函數(shù)。
當(dāng)B類(lèi)繼承自A類(lèi),內(nèi)存里B類(lèi)的數(shù)據(jù)成員會(huì)緊接A類(lèi)數(shù)據(jù)成員之后,如圖所示。

繼承對(duì)類(lèi)布局的影響

需要說(shuō)明的是,當(dāng)class中有虛函數(shù)的時(shí)候,或者是繼承的類(lèi)中有虛函數(shù)的時(shí)候,通常會(huì)在類(lèi)的布局最前端加入一個(gè)虛表指針,它指向名為虛函數(shù)表的一個(gè)數(shù)據(jù)結(jié)構(gòu),因?yàn)橹羔樖莍nt類(lèi)型的。

了解內(nèi)存布局的意義是,當(dāng)我們寫(xiě)類(lèi)和結(jié)構(gòu)體的時(shí)候,最優(yōu)化的處理方式是自己按照內(nèi)存布局規(guī)則把數(shù)據(jù)排列好,從而可以降低類(lèi)或者結(jié)構(gòu)體所占的大小。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 結(jié)構(gòu)體和共同體的區(qū)別。 定義: 結(jié)構(gòu)體struct:把不同類(lèi)型的數(shù)據(jù)組合成一個(gè)整體,自定義類(lèi)型。共同體uni...
    breakfy閱讀 2,265評(píng)論 0 22
  • 1. C++基礎(chǔ)知識(shí)點(diǎn) 1.1 有符號(hào)類(lèi)型和無(wú)符號(hào)類(lèi)型 當(dāng)我們賦給無(wú)符號(hào)類(lèi)型一個(gè)超出它表示范圍的值時(shí),結(jié)果是初始值...
    Mr希靈閱讀 18,158評(píng)論 3 82
  • 一個(gè)博客,這個(gè)博客記錄了他讀這本書(shū)的筆記,總結(jié)得不錯(cuò)。《深度探索C++對(duì)象模型》筆記匯總 1. C++對(duì)象模型與內(nèi)...
    Mr希靈閱讀 5,881評(píng)論 0 13
  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛(ài)閱讀 2,241評(píng)論 0 7
  • ———————————————回答好下面的足夠了---------------------------------...
    恒愛(ài)DE問(wèn)候閱讀 1,835評(píng)論 0 4

友情鏈接更多精彩內(nèi)容