在Metal中使用数组的结构

时间:2017-06-25 11:33:37

标签: arrays swift memory struct metal

我的目标是在swift中创建一个包含数组的结构,我可以将其打包到金属缓冲区中以用于内核函数。

类似的东西:

struct StructA  {
  var listA: [StructB] = [StructB](repeating: StructB(), count: 100)
  var listB: [StructC] = [StructC](repeating: StructC(), count: 100)
  var primitiveA: Int = 0
  var primitiveB: Int = 0
}

我不太确定如何解决这个问题。上面的示例显然不起作用,因为数组实际上不在StructA内部。我的猜测是必须有一种方法在结构体内创建一个数组,以便使用的内存在结构体内物理对齐。

目前我的解决方法是将listA和listB打包到两个单独的缓冲区中,将它们设置为我的内核函数的参数,并在内核函数中将它们分配给在每个线程中创建的StructA,这是一种疯狂的冗余。

kernel void functionA(
  const device StructB *listA [[buffer(0)]],
  const device StructC *listB [[buffer(1)]],
  device int &primitiveA [[buffer(2)]],
  device int &primitiveB [[buffer(3)]],
) {
  StructA structA = StructA(); //create a struct in each and every thread
  structA.listA = listA;       //and assign the same lists to the struct
  structA.listB = listB;       //that is the same in every thread
  structA.primitiveA = primitiveA;
  structA.primitiveB = primitiveB;

  //do stuff with structA
}

这个例子可能并不完美,但我认为问题已得到充分描述。我希望有一个解决方案。如果不是通过创建可忍受的结构,我也会使用任何其他解决冗余的解决方案。

1 个答案:

答案 0 :(得分:1)

这样做需要在堆栈上分配数组listA和listB,这是目前不可能的,因为数组没有固定的大小,因此在堆上分配。

要解决此问题,您可以使用元组而不是数组或在C代码中声明您的结构。您甚至可以将结构声明与金属代码共享,方法是将它们放在C头文件中。

This answer可能对您有帮助。