1

我用 Metal 写了一个简单的点着色器,但它运行得很慢,只有 10K 点。所有顶点都在交错缓冲区中,它们具有 4 字节对齐的属性,但它仍然非常慢(>70ms CPU 和 ~20ms GPU)。顶点着色器大约需要 9 毫秒,而片段着色器需要 12-13 毫秒(!)。

#include <metal_stdlib>
#include <metal_common>
#include <simd/simd.h>

using namespace metal;

typedef struct {
  float4 position [[ attribute(0) ]];
  float4 color [[ attribute(1) ]];
} Vertex;

typedef struct {
  float4x4 mvpMatrix;
} Uniforms;

typedef struct {
  float4 position [[ position ]];
  float4 color;
  float pointSize [[ point_size ]];
} ColorInOut;

constant float POINT_SIZE = 3.0f;

vertex ColorInOut pointCloudVertex(Vertex vert [[ stage_in ]], constant Uniforms& uniforms [[ buffer(1) ]])
{
  ColorInOut out;
  out.position = uniforms.mvpMatrix * vert.position;
  out.pointSize = POINT_SIZE;
  out.color = vert.color;
  return out;
}

fragment float4 pointCloudFragment(ColorInOut in [[ stage_in ]])
{
  return in.color;
};

撇开 CPU 不谈,这真的很奇怪,因为我只是在需要时重新加载缓冲区,你有没有看到任何可能损害 GPU 性能的东西?

更新

当我优化一个占用大量 CPU 的独立函数时,GPU 的使用率也下降了。现在整个着色器在大约 1 毫秒内执行。我很想知道 GPU 时间是否如此之高,因为它正在等待 CPU 执行下一个周期。

4

0 回答 0