Metal IOS 简单直通计算内核在 iPhone 5s 上需要 10 毫秒



我创建了简单的直通计算内核

kernel void filter(texture2d<float, access::read> inTexture [[texture(0)]],
                         texture2d<float, access::write> outTexture [[texture(1)]],
                         uint2 gridPos [[ thread_position_in_grid ]]) {
  float4 color = inTexture.read(gridPos);
  outTexture.write(color, gridPos);
}

测量执行时间

[self.timer start];
[commandBuffer commit];
[commandBuffer waitUntilCompleted];
CGFloat ms = [self.timer elapse];

计时器类的工作方式如下:

- (void)start {
  self.startMach = mach_absolute_time();
}  
- (CGFloat)elapse {
  uint64_t end = mach_absolute_time();
  uint64_t elapsed = end - self.startMach;
  uint64_t nanosecs = elapsed * self.info.numer / self.info.denom;
  uint64_t millisecs = nanosecs / 1000000;
  return millisecs;
}

调度呼叫:

static const NSUInteger kGroupSize = 16;
- (MTLSize)threadGroupSize {
  return MTLSizeMake(kGroupSize, kGroupSize, 1);
}
- (MTLSize)threadGroupsCount:(MTLSize)threadGroupSize {
  return MTLSizeMake(self.provider.texture.width / kGroupSize,
                 self.provider.texture.height / kGroupSize, 1);
}
[commandEncoder dispatchThreadgroups:threadgroups 
               threadsPerThreadgroup:threadgroupSize];

在 512x512 RGBA 图像上给我 13 毫秒,如果我执行更多传递,它会变线性。

这是对的吗?对于实时应用程序来说,开销似乎太大了。

众所周知,计算内核在 A7 处理器上的开销相当高。但是,需要考虑的一件事是,这基本上是您可以运行的最不讨人喜欢的测试:一次性线程组调度可能需要 ~2ms 才能调度,但后续调度的调度速度可以快一个数量级。此外,延迟隐藏在这里的可能性很小。实际上,更复杂的内核可能不会花费更长的时间来执行,并且如果可以将其与可能正在执行的任何渲染交错,您可能会发现性能是可以接受的。

最新更新