[開發日記][UnrealEngine] MemoryMapped File

posted in: UnrealEngine, 開發日誌 | 0

前幾天在看資料看到MemoryMapped File這個東西,好奇unreal目前對於MemoryMapped File支援度如何,因此花了一些時間看了一下並做一些實驗。由於iOS上可用的記憶體實在太少,想說如果沒開的話可以試著把他開起來。

簡單來說,這東西能夠讓我們直接把硬碟上的檔案直接map到我們的virtual memory中,直接用記憶體相關操作做檔案IO,這不僅可以少掉記憶體壓力,也能夠少掉把檔案讀寫進記憶體時間。由於他佔用的是virtual memory的空間,因此在64位元的系統,他的上限可以對應到2^64次方,就是8EB;相對於32位元的系統只有4GB。雖然4.27在Android上還支援使用32位元的armv7,但UE5就只剩下arm64了。

MemoryMapped File有console command可以開關:mmio.enable。

mmio這個名詞用在這裡其實還蠻讓人困惑的,他跟MemoryMapped File的概念不太一樣。

更進一步的把mmio這個關鍵字餵進去搜尋,會找到2個地方有出現這個名詞:

MMIO:Memory mapping I/O,主要是用在跟外部硬體互動的機制,很久以前會需要發特殊的硬體指令,但現在(不確定這個現代是從什麼時候)喜歡透過正規的記憶體操作來跟硬體互動,現在的硬體大多支援這個機制。作業系統會保留一塊區間給外部硬體,一個記憶體位置對應一個硬體裝置,在程式中操作記憶體等同於操作裝置。細節我也沒玩過,google到的使用方法是做一個struct,然後針對某個係保留的記憶體位置強制做轉型,之後就可以在程式中對該物件做操作。
1. data-in register
2. data-out register
3. status register
4. control register
例如手把controller的區間是200–20F(512-527)

1. MultiMedia File I/O:Unreal Audio使用
2. MemoryMapped File

結論來說,目前引擎只有iOS有開啟支援,且4.27限定在CompressedAnimation跟UnrealAudio這二個asset上、5.0則只支援UnrealAudio。看來UnrealEngine對於iOS這種記憶體有限的裝置,還是有想一些應對的方法來減緩記憶體的壓力。沒有全部asset都開的原因,可能是因為flash memory有寫入次數的問題。雖然目前我還不確定為什麼5.0要把CompressedAnimation關掉,可能跟上面的原因一樣。

有試著開其他type的asset,結果馬上就遇到了檔案alignment的check error;測試開了windows,也會同樣的error也會發生。註解掉error是能夠繼續運行,但就沒深入去研究有什麼副作用(side effect)就是。

各別Asset的開關需要去調整FGenericPlatformProperties中的SupportsMemoryMappedFiles、SupportsMemoryMappedAudio以及SupportsMemoryMappedAnimation。要針對各平台的話,例如IOS,就是在FIOSPlatformProperties中實作這三個function並回傳true。

struct FIOSPlatformProperties
	: public FGenericPlatformProperties
{
	
	static FORCEINLINE bool SupportsMemoryMappedFiles()
	{
		return true;
	}
	static FORCEINLINE bool SupportsMemoryMappedAudio()
	{
		return true;
	}
	static FORCEINLINE bool SupportsMemoryMappedAnimation()
	{
		return false;
	}
};

要注意的是,在引擎中的用法是先檢查SupportsMemoryMappedFiles是不是true,再根據各別的Asset去看要不要開起來,也就是說二個條件都要符合,例如Animation的檢查如下:

bool bUseMapping = FPlatformProperties::SupportsMemoryMappedFiles() && FPlatformProperties::SupportsMemoryMappedAnimation();

註:
想強制把功能開起來,需調整以下東西
1. FBulkDataBase::Serialize把bAttemptFileMapping強制設成true,
2. DefaultEngine.ini中的
[MemoryMappedFiles]
MasterEnable=true
Alignment=16384

Leave a Reply

Your email address will not be published. Required fields are marked *