最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

Unity ECS 內(nèi)存分配器原理詳解

2022-02-25 19:52 作者:小小游戲開發(fā)程序員  | 我要投稿

ECS 為什么會(huì)高效,性能好,Entity的內(nèi)存布局與分配就是非常重要的部分,今天我們一起來分析一下Unity ECS 架構(gòu)里面如何來做高效的內(nèi)存分配器。這種思路也可以給我們做內(nèi)存分配提供很好的一個(gè)思路。

1: ECS 里面基本的一些概念

Unity ECS框架里面有幾個(gè)重要的概念:

Entity, ComponentData, System,Archetype, EntityManager, World;

ComponentData:

組件數(shù)據(jù),開發(fā)的時(shí)候,可以把每個(gè)功能相關(guān)的數(shù)據(jù)放到ComponentData里面。

Entity:

對(duì)象實(shí)體,純數(shù)據(jù)對(duì)象,里面包含了一個(gè)個(gè)的ComponentData, 每個(gè)相關(guān)功能使用的數(shù)據(jù)我們放Entity的ComponentData里面, 如圖:

編輯

ystem:

具體算法邏輯的實(shí)現(xiàn),System算法數(shù)據(jù)基于Entity里面對(duì)應(yīng)處理的ComponentData。游戲引擎每次Update的時(shí)候,System都會(huì)根據(jù)每個(gè)Entity里面的它使用的ComponentData, 來更新數(shù)據(jù)完成計(jì)算。

EntityManager:

負(fù)責(zé)Entity相關(guān)類型信息,對(duì)象實(shí)體的創(chuàng)建與管理。

Archetype:

Entity是由多個(gè)ComponentData組成的,每種Entity類型都會(huì)對(duì)應(yīng)一個(gè)Archetype, 里面描述了這個(gè)Entity類型以及相關(guān)的布局。Archetype由EntityManager創(chuàng)建出來,創(chuàng)建出來后這個(gè)類型的Entity的大小,包含的組件數(shù)據(jù),內(nèi)存布局都確定了。

World:

世界包含多個(gè)Entity組成Entity群體,通過世界把這些Entity群體孤立起來。Unity里面可以同時(shí)擁有多個(gè)不同的世界, 每個(gè)世界獨(dú)立包含EntityManager, 與Systems, 在世界里面創(chuàng)建出來的一個(gè)Entity,只屬于這個(gè)世界。世界里每個(gè)System也只能迭代一個(gè)世界里面的Entity實(shí)體數(shù)據(jù)。你可以創(chuàng)建多個(gè)World。

總結(jié)一下Unity ECS的使用步驟與邏輯關(guān)系:

(1) 創(chuàng)建一個(gè)ECS的World;

(2) 使用World的EntityManager為不同Entity類型創(chuàng)建出來Archetype;

(3) 基于Archetype, 我們創(chuàng)建出來Entity內(nèi)存對(duì)象, 并初始化Entity里面每個(gè)ComponentData數(shù)據(jù);

(4)為ECS World編寫System算法,World會(huì)調(diào)用System算法來迭代每個(gè)Entity里的相關(guān)ComponentData;

編輯切換為居中

2: ECS 高效的內(nèi)存模型與布局

作為架構(gòu)師,設(shè)計(jì)框架數(shù)據(jù)結(jié)構(gòu)由為關(guān)鍵。特別對(duì)于游戲開發(fā),要處理迭代成百上千個(gè)游戲物體。高效的內(nèi)存模型與布局如何實(shí)現(xiàn)? 首先要明白怎么樣布局內(nèi)存才會(huì)高效。內(nèi)存模型布局高效主要從兩個(gè)方面來考慮:

1:內(nèi)存對(duì)齊。

CPU訪問不同地址的內(nèi)存數(shù)據(jù)的時(shí)候,如果內(nèi)存地址基于2^n 數(shù)據(jù)對(duì)齊(n根據(jù)CPU而定),訪問最為高效。例如我們以16字節(jié)數(shù)據(jù)對(duì)齊,那么對(duì)象內(nèi)存開始排布的時(shí)候, 從地址能整除16的內(nèi)存位置開始排布。高效的內(nèi)存布局,對(duì)象實(shí)例內(nèi)存地址要對(duì)齊,對(duì)象實(shí)例里面的每個(gè)數(shù)據(jù)成員內(nèi)存地址也要對(duì)齊。Entity的內(nèi)存分配與內(nèi)存布局, 在創(chuàng)建Entity的時(shí)候,ECS系統(tǒng)就會(huì)注意Entity的內(nèi)存對(duì)齊,同時(shí)也會(huì)注ComponentData在Entity里面排布的內(nèi)存對(duì)齊,如果沒有對(duì)齊,就會(huì)空一些出來。比如16字節(jié)對(duì)齊,一個(gè)ComponentData只有14個(gè)字節(jié),實(shí)際上排布下一個(gè)ComponentData的時(shí)候是從16字節(jié)開始排布的。

2: CPU通過地址來取到內(nèi)存數(shù)據(jù)的時(shí),數(shù)據(jù)排布一起取的速度會(huì)更快。

ECS天然就具有這種優(yōu)勢。所有的邏輯代碼迭代都是基ComponentData的,也就是算法迭代訪問處理的數(shù)據(jù)都在一起,在一個(gè)ComponentData里面。這樣訪問數(shù)據(jù)高效,避免了地址的來回跳轉(zhuǎn)。

3: Entity內(nèi)存分配器 Chunk的設(shè)計(jì)

大量的Entity的創(chuàng)建與銷毀,大量不同類型的數(shù)據(jù)對(duì)象交叉創(chuàng)建,很容易造成內(nèi)存碎片。何為內(nèi)存碎片?給大家舉個(gè)例子,對(duì)象A,對(duì)象B(100字節(jié)),對(duì)象C連續(xù)排布,對(duì)象B銷毀,內(nèi)存釋放,同時(shí)又請求分配對(duì)象D(80字節(jié)),系統(tǒng)在原來對(duì)象B的地方把一塊內(nèi)存分配給對(duì)象D,還剩了一小塊內(nèi)存(20字節(jié))。而這一小塊內(nèi)存,無法分配給當(dāng)前系統(tǒng)的任何一個(gè)對(duì)象,這樣,這小快內(nèi)存就再也無法使用了,造成內(nèi)存碎片,隨著系統(tǒng)不斷運(yùn)行,隨著更多大量的創(chuàng)建與釋放,內(nèi)存碎片越來越多,分配/釋放效率也越來越低。最終讓系統(tǒng)越來越慢。解決這種大量創(chuàng)建與銷毀,我們一般采用Cache內(nèi)存池來做。那Unity ECS架構(gòu)里面內(nèi)存池是如何設(shè)計(jì)的呢?接下來我們來分析ECS里面基于Chunk的內(nèi)存分配器。不同的Archetype,所對(duì)應(yīng)的Entity的內(nèi)存不一樣,系統(tǒng)可能有N中不同的Archetype,而且Archetype是用戶根據(jù)組件數(shù)據(jù)組合創(chuàng)建而來。

綜上Unity ECS 是這樣設(shè)計(jì)內(nèi)存分配緩存池:

(1) 基于固定大小的Chunk來做內(nèi)存緩存池。每個(gè)Chunk大小為16KB(引用來自于UnityECS 文檔)

(2) 當(dāng)Archetype 確定后,Entity的內(nèi)存大小就確定下來,每個(gè)Chunk能分配的當(dāng)前的Entity數(shù)目就能確定下來?;贏rchetype創(chuàng)建Entity的時(shí)候,首先從內(nèi)存池里面拿一個(gè)Chunk, 然后根據(jù)每個(gè)Chunk可創(chuàng)建Entity數(shù)目,從Chunk里面把Entity分配出去,如果chunk分配完畢,從chunk內(nèi)存緩存池里面再拿一個(gè)Chunk。由于基于Archetype創(chuàng)建,這個(gè)Archetype的所有Entity內(nèi)存大小都是一樣的,等釋放的時(shí)候,我們就可以基于Archetype把Entity緩存起來,重復(fù)使用之前的Entity。

對(duì)于OS而言,ECS框架基于chunk來分配和釋放內(nèi)存,避免了內(nèi)存碎片(大小都一樣)。對(duì)于ArcheType而言,又基于特定ArcheType的Entity來做內(nèi)存緩存,分配和釋放都非常高效。

看完Unity ECS的架構(gòu)設(shè)計(jì)與內(nèi)存布局,我們在其他地方做ECS架構(gòu)設(shè)計(jì)(游戲服務(wù)器)就有了一個(gè)很好的參考,設(shè)計(jì)萬變不離其中,大家可以好好體會(huì)一下。

更多教學(xué):

https://bycwedu.vipwan.cn/promotion_channels/2146264125bycwedu.vipwan.cn/promotion_channels/2146264125bycwedu.vipwan.cn


Unity ECS 內(nèi)存分配器原理詳解的評(píng)論 (共 條)

分享到微博請遵守國家法律
灵璧县| 大冶市| 思南县| 东安县| 航空| 南开区| 文安县| 西畴县| 天水市| 大石桥市| 龙江县| 禹州市| 许昌市| 塘沽区| 兰州市| 淮北市| 鹰潭市| 张家界市| 长宁区| 萍乡市| 东乡| 临漳县| 嵩明县| 梅河口市| 崇阳县| 盱眙县| 沧源| 德昌县| 民丰县| 贵州省| 图木舒克市| 连城县| 香河县| 禄丰县| 南宫市| 山西省| 进贤县| 扎赉特旗| 宝应县| 牡丹江市| 万山特区|