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 ミリ秒で実行されます。CPU が次のサイクルを実行するのを待っていたため、GPU 時間が非常に高かったかどうか知りたいです。