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

时间:2017-09-26 16:02:10

标签: ios swift xcode metal

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

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

// 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等其他类型的策略?

1 个答案:

答案 0 :(得分:16)

让我们首先谈谈为什么你想要对齐缓冲区,然后我们可以谈谈逐位运算。

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

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

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

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