ios - 在 MacBook Pro 和 iMac 之间使用 Metal Performance Shaders 的结果不一致
问题描述
我正试图第一次涉足 GPU 编程领域。我想我会从一些简单的东西开始,使用预制的内核(因此是 MPS),然后尝试向 GPU 发出命令。
我的尝试是简单地将 1 到 1000 之间的所有值相加。我将每个值放在一个 1x1 矩阵中并使用 MPS 矩阵求和。
在我的 MacBook Pro 上,这可以按我的预期工作。
在我的 iMac 上,它给出 [0.0] 作为结果。我认为这与内存有关,因为我在 MacBook Pro 上使用 iGPU,在 iMac 上使用 dGPU,但是,据我所知, storageModeShared 不应该导致这种情况。我什至尝试在尝试读取结果矩阵之前将 .synchronize() 添加到结果矩阵中,即使我很确定 storageModeShared 不需要它。
代码并不优雅,因为它只是为了快速理解使用 MPS 发出命令的工作原理,我尝试在不跟踪结构的情况下修复问题一段时间,但它仍然应该很容易阅读;如果不让我知道,我会重构它。
除了 print(output) 之外,打印语句只是为了尝试和调试
我讨厌粘贴这么多代码,但恐怕我无法真正隔离我的问题。
import Cocoa
import Quartz
import PlaygroundSupport
import MetalPerformanceShaders
let device = MTLCopyAllDevices()[0]
print(MTLCopyAllDevices())
let shaderKernel = MPSMatrixSum.init(device: device, count: 1000, rows: 1, columns: 1, transpose: false)
var matrixList: [MPSMatrix] = []
var GPUStorageBuffers: [MTLBuffer] = []
for i in 1...1000 {
var a = Float32(i)
var b: [Float32] = []
let descriptor = MPSMatrixDescriptor.init(rows: 1, columns: 1, rowBytes: 4, dataType: .float32)
b.append(a)
let buffer = device.makeBuffer(bytes: b, length: 4, options: .storageModeShared)
GPUStorageBuffers.append(buffer!)
let GPUStoredMatrices = MPSMatrix.init(buffer: buffer!, descriptor: descriptor)
matrixList.append(GPUStoredMatrices)
}
let matrices: [MPSMatrix] = matrixList
print(matrices.count)
print("\n")
print(matrices[4].debugDescription)
print("\n")
var printer: [Float32] = []
let pointer2 = matrices[4].data.contents()
let typedPointer2 = pointer2.bindMemory(to: Float32.self, capacity: 1)
let buffpoint2 = UnsafeBufferPointer(start: typedPointer2, count: 1)
buffpoint2.map({value in
printer += [value]
})
print(printer)
let CMDQue = device.makeCommandQueue()
let CMDBuffer = CMDQue!.makeCommandBuffer()
var resultMatrix = MPSMatrix.init(device: device, descriptor: MPSMatrixDescriptor.init(rows: 1, columns: 1, rowBytes: 4, dataType: .float32))
shaderKernel.encode(to: CMDBuffer!, sourceMatrices: matrices, resultMatrix: resultMatrix, scale: nil, offsetVector: nil, biasVector: nil, start: 0)
print(CMDBuffer.debugDescription)
CMDBuffer!.commit()
print(CMDBuffer.debugDescription)
print(CMDQue.debugDescription)
let GPUStartTime = CACurrentMediaTime()
CMDBuffer!.waitUntilCompleted()
var output = [Float32]()
resultMatrix.synchronize(on: CMDBuffer!)
let pointer = resultMatrix.data.contents()
let typedPointer = pointer.bindMemory(to: Float32.self, capacity: 1)
let buffpoint = UnsafeBufferPointer(start: typedPointer, count: 1)
buffpoint.map({value in
output += [value]
})
print(output)
let finish = GPUStartTime - CACurrentMediaTime()
print("\n")
print(finish)
解决方案
推荐阅读
- ios - 从 Firebase 查询中检索深层数据(iOS、Swift 4)
- flutter - 如何处理不同的图标大小
- c - 共享对象上的 setuid 位
- gpu - 训练分割模型,4 个 GPU 工作,1 个填充并得到:“CUDA 错误:内存不足”
- javascript - 带有标签样式的复选框的不确定css样式
- jquery - 当 URL 包含预定义值时插入 html
- python - “系统错误:
在 Python 中返回带有错误集的结果 - typescript - 使用参考时,Typescript Omit 不显示错误
- javascript - Javascript - 共享指针范式
- scala - Scala初学者有一些问题