作为this answer的后续问题。我试图用Metal中的内核函数替换运行在CPU上的for-loop来并行化计算并提高性能。在iOS中为MTLBuffer使用的数据分配内存金属
我的功能基本上是一个卷积。由于我反复接收到我输入数组值的新数据(数据源自AVCaptureSession
),因此似乎使用newBufferWithBytesNoCopy:length:options:deallocator:
是创建MTLBuffer
对象的明智选择。下面是相关代码:
id <MTLBuffer> dataBuffer = [device newBufferWithBytesNoCopy:dataVector length:sizeof(dataVector) options:MTLResourceStorageModeShared deallocator:nil];
id <MTLBuffer> filterBuffer = [device newBufferWithBytesNoCopy:filterVector length:sizeof(filterVector) options:MTLResourceStorageModeShared deallocator:nil];
id <MTLBuffer> outBuffer = [device newBufferWithBytesNoCopy:outVector length:sizeof(outVector) options:MTLResourceStorageModeShared deallocator:nil];
运行此我得到以下错误:
failed assertion `newBufferWithBytesNoCopy:pointer 0x16fd0bd48 is not 4096 byte aligned.'
现在,我没有分配任何内存,但(用于测试目的)只是创建一个空数组一个固定大小的浮游物并用随机数填充。所以我的主要问题是:
如何浮点数分配到这些阵列以下列要求得到满足
This value must result in a page-aligned region of memory.
此外,一些其他问题的正确方法是:
- 不它甚至可以用
newBufferWithBytesNoCopy
方法创建MTLBuffer
,或者在性能方面复制数据不是真正的问题? (我的实际数据将包括每个视频帧大约43'000浮点值。) - 是
MTLResourceStorageModeShared
为MTLResourceOptions
正确的选择的API参考说
The storage allocation of the returned new MTLBuffer object is the same as the pointer input value. The existing memory allocation must be covered by a single VM region, typically allocated with vm_allocate or mmap. Memory allocated by malloc is specifically disallowed.
这是否仅适用于输出缓冲区,还是应该与
MTLBuffer
使用的所有对象的存储分配不应与malloc
?
嗨@warrenm关于循环虽然缓冲区一个简单的问题。我希望实时处理数据,但是我在'AVCaptureVideoDataOutput'上设置了'setAlwaysDiscardsLateVideoFrames:YES',所以在我完成包括Metal部分在内的所有旧计算之前,永远不会处理新帧。在这种情况下,是否需要创建一个缓冲池,因为我总是可以使用相同的缓冲区? –
您不希望在Metal处理中阻止捕获输出队列,因此您将工作交给Metal命令队列以异步执行。根据处理帧需要多长时间,您可能会同时有多个帧在飞行。如果是这样的话,你仍然应该使用缓冲池来避免读写冲突或不必要的阻塞。如果你发现你总是(或经常)在下一帧到来之前完成处理,你可以减少池的大小,甚至完全消除它。 – warrenm
我不明白。我认为用上面提到的方法丢弃晚期视频帧确实是这样的,即强制处理总是必须在处理下一帧之前完成,并丢弃早到的东西。 –