这段代码如何在swift中找到Struct的内存对齐大小?为什么需要二进制操作?

J.D*_*Doe 10 xcode ios swift metal

我正在通过Metal iOS Swift示例尝试了解他们建议的三重缓冲实践.这是在演示内部显示的统一动画.

据我所知,对齐内存只是以一个特定的增量开始,这是设备真正喜欢的某个字节数的倍数.我的困惑是这行代码

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

他们用它来查找Uniforms结构的大小和字节.我很困惑为什么在这里有二进制操作我真的不确定他们做了什么.

如果它有助于这个对齐的大小用于创建这样的缓冲区.我很确定缓冲区会自动分配字节对齐的内存,因此可以用作制服的内存存储位置.

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

所以基本上不是经历自己分配字节对齐内存的麻烦,而是让金属为它们做.

在那个时候,他们的策略时,他们没有使用任何理由let allignedUniformsSize =不会为其他类型,比如上班IntFloat等?

war*_*enm 16

让我们首先谈谈为什么你想要对齐缓冲区,然后我们可以讨论按位算术.

我们的目标是分配一个Metal缓冲区,它可以存储我们制服的三个(三重缓冲)副本(这样我们可以在GPU从另一个读取时写入缓冲区的一部分).为了从这三个副本中的每个副本中读取,我们在绑定缓冲区时提供偏移量,例如currentBufferIndex * uniformsSize.某些Metal设备要求这些偏移量为256的倍数,因此我们需要使用像currentBufferIndex * alignedUniformsSize偏移量这样的东西.

我们如何将整数"舍入"到256的下一个最高倍数?我们可以通过删除"未对齐"大小的最低8位来实现它,有效地向下舍入,然后添加256,这使我们成为下一个最高倍数.向下舍入部分是通过按位AND运算得到的,其1的补码(~)为255,其中(32位)为0xFFFFFF00.通过添加0x100(256)来完成舍入.

有趣的是,如果基本大小已经对齐,则该技术无论如何都会虚假地舍入(例如,从256到512).对于整数除法的成本,您可以避免这种浪费:

let alignedUniformsSize = ((MemoryLayout<Uniforms>.size + 255) / 256) * 256
Run Code Online (Sandbox Code Playgroud)