我用 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 执行下一个周期。