2017-09-26 73 views
9

我正在通過Metal iOS Swift示例嘗試理解他們所建議的三重緩衝實踐。這顯示在統一動畫的演示中。這段代碼如何在swift中找到struct的內存對齊大小?爲什麼需要二元操作?

據我所知,它對齊的內存只是從一個特定的增量開始,這個增量是設備真正喜歡的字節數量的倍數。我的困惑是這行代碼

// The 256 byte aligned size of our uniform structure 
let alignedUniformsSize = (MemoryLayout<Uniforms>.size & ~0xFF) + 0x100 

他們用它來找到Uniforms結構的大小和字節。我很困惑爲什麼在這裏有二元操作,我真的不知道他們在做什麼。

如果它幫助這個對齊的大小用於創建像這樣的緩衝區。我確信緩衝區會自動分配字節對齊的內存,並且此後將用作制服的內存存儲位置。

let buffer = self.device.makeBuffer(length:alignedUniformsSize * 3, options:[MTLResourceOptions.storageModeShared]) 

所以,基本上,而不是經歷自己分配字節對齊內存的麻煩,他們讓金屬爲他們做。

是否有任何理由說他們使用的策略let allignedUniformsSize =不適用於其他類型,如IntFloat等?

回答

12

讓我們先來談談爲什麼你想要對齊緩衝區,然後我們可以談論按位算術。

我們的目標是分配一個金屬緩衝區,可以存儲我們的制服的三個(三緩衝)副本(以便我們可以在GPU讀取另一個時寫入緩衝區的一部分)。爲了讀取這三個副本中的每一個,我們在綁定緩衝區時提供一個偏移量,如currentBufferIndex * uniformsSize。某些金屬設備需要這些偏移量爲256的倍數,所以我們需要使用類似currentBufferIndex * alignedUniformsSize這樣的偏移量。

我們如何「整理」一個整數到256的下一個最高倍數?我們可以通過刪除「未對齊」大小的最低8位來有效地舍入,然後添加256,從而得到下一個最高倍數。向下取整部分是通過按位與邏輯1的補碼(~)255來實現的,其中(32位)是0xFFFFFF00。向上舍入是通過加上0x100來完成的,即256。

有趣的是,如果基本大小已經對齊,則該技術無論如何都會虛假地舍入(例如,從256到512)。對於整數除法的代價,您可以避免這種浪費:

let alignedUniformsSize = ((MemoryLayout<Uniforms>.size + 255)/256) * 256 
+0

非常感謝這行,正常的算術版本更具可讀性! – zsero

相關問題