我很难理解Swift中simd模块中的simd_packed向量。我以float4为例,希望有人能帮上忙。
我的理解是simd_float4是SIMD4< Float>的typealias,MemoryLayout<SIMD4< Float>>.alignment = 16 (字节),因此是MemoryLayout<simd_float4>.alignment = 16。合乎道理。
但以下几点我不明白:simd_packed_float4也是SIMD4<Float>的typealias。MemoryLayout<simd_packed_float4>.alignment = 16也是如此。
那么,simd_packed_float4中“打包”的意义是什么呢?文档中提到的“轻松对齐”在哪里?
在金属着色器语言规范(版本2.4) ( https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf)的表2.4 (第28页)中,它说packed_float4的对齐是4(这也是标量类型float的对齐),所以这是一个“宽松的对齐”(与16相比)。这本身是有意义的,但我如何协调这一点和上面的(simd_packed_float4是SIMD4<Float>和MemoryLayout<simd_packed_float4> = 16的类型别名)?
发布于 2021-06-12 11:39:42
实际上,我认为在Swift中不可能像这样轻松地与打包类型对齐。我认为Swift编译器不能将对齐属性带到实际的Swift接口。
我认为这使得simd_packed_float4在Swift中毫无用处。
我已经做了一个游乐场来检查这一点,并按计划使用它不起作用。
import simd
MemoryLayout<simd_float4>.stride
MemoryLayout<simd_packed_float4>.alignment
let capacity = 8
let buffer = UnsafeMutableBufferPointer<Float>.allocate(capacity: capacity)
for i in 0..<capacity {
buffer[i] = Float(i)
}
let rawBuffer = UnsafeMutableRawBufferPointer.init(buffer)
let readAligned = rawBuffer.load(fromByteOffset: MemoryLayout<Float>.stride * 4, as: simd_packed_float4.self)
print(readAligned)
let readUnaligned = rawBuffer.load(fromByteOffset: MemoryLayout<Float>.stride * 2, as: simd_packed_float4.self)
print(readUnaligned)它将输出以下内容
SIMD4<Float>(4.0, 5.0, 6.0, 7.0)
Swift/UnsafeRawPointer.swift:900: Fatal error: load from misaligned raw pointer如果您确实需要加载未对齐的simd_float4向量或将其放入缓冲区中,我建议您只做一个扩展来完成此操作,因此所有的对齐都是这样的
extension UnsafeMutableRawBufferPointer {
func loadFloat4(fromByteOffset offset: Int) -> simd_float4 {
let x = rawBuffer.load(fromByteOffset: offset + MemoryLayout<Float>.stride * 0, as: Float.self)
let y = rawBuffer.load(fromByteOffset: offset + MemoryLayout<Float>.stride * 1, as: Float.self)
let z = rawBuffer.load(fromByteOffset: offset + MemoryLayout<Float>.stride * 2, as: Float.self)
let w = rawBuffer.load(fromByteOffset: offset + MemoryLayout<Float>.stride * 3, as: Float.self)
return simd_float4(x, y, z, w)
}
}
let readUnaligned2 = rawBuffer.loadFloat4(fromByteOffset: MemoryLayout<Float>.stride * 2)
print(readUnaligned2)或者,您甚至可以使其泛型
https://stackoverflow.com/questions/67943802
复制相似问题