少年、これは大きなテーマです。
まず、明らかなことから始めましょう。CPUから関数(任意の関数)を呼び出しているので、少なくとも部分的にCPUで実行する必要があります。したがって、問題は実際には、CPUでどれだけの作業が行われ、GPUでどれだけの作業が行われるかということです。
次に、GPUがコマンドを実行できるようにするために、CPUはコマンドの説明を準備して渡す必要があります。ここでの最小セットは、実行する操作のデータだけでなく、何を実行するかを説明するコマンドトークンです。CPUがGPUをトリガーしてコマンドを実行する方法も重要です。ほとんどの場合、これは高価であるため、CPUは頻繁に実行するのではなく、コマンドをコマンドバッファーにバッチ処理し、GPUが処理するためにバッファー全体を送信するだけです。
作業をGPUに渡すことは、自由な運動ではないと言っても過言ではありません。そのコストは、CPUで関数を実行するだけではなく、(何について話しているかに関係なく)考慮しなければなりません。
一歩後退して、GPUが必要な理由を自問する必要があります。実際のところ、純粋なCPU実装がその役割を果たします(AshleysBrainが言及しているように)。GPUの能力は、以下を処理するための設計に由来します。
- 特殊なタスク(ラスタライズ、ブレンディング、テクスチャフィルタリング、ブリッティングなど)
- CPUがシングルスレッド作業を処理するように設計されている場合、高度に並列化されたワークロード(DeadMGは彼の回答でそれを指摘しています)。
そして、これらは、チップに何を入れるかを決定するために従うべき指針です。それらから利益を得ることができるものはすべて、GPUで実行する必要があります。他のものはCPU上にあるべきです。
ちなみに面白いですね。GLの一部の機能(ほとんどの場合、非推奨になる前)は、実際には明確に描写されていません。ディスプレイリストは、おそらくそのような機能の最良の例です。各ドライバーは、GLディスプレイリストのセマンティクスが保持されている限り、後で実行するために、ディスプレイリストストリームからGPUに(通常はコマンドバッファー形式で)必要なだけプッシュできます(これはやや難しいです)全般的)。そのため、一部の実装では、表示リスト内の呼び出しの限られたサブセットのみを計算形式にプッシュし、残りのコマンドストリームをCPUで単純に再生することを選択します。
選択は、GPUで実行する価値があるかどうかが不明なもう1つの方法です。
最後に、一般的に、API呼び出しとCPUまたはGPUのいずれかの作業量との間にはほとんど相関関係がないことを言わなければなりません。状態設定APIは、ドライバーデータのどこかで構造を変更するだけの傾向があります。この効果は、ドローなどが呼び出されたときにのみ表示されます。
GLAPIの多くはそのように機能します。その時点でglEnable(GL_BLEND)
、CPUとGPUのどちらで実行されているかを尋ねるのはかなり無意味です。重要なのは、Drawが呼び出されたときにGPUでブレンディングが発生するかどうかです。したがって、その意味では、ほとんどのGLエントリポイントはまったく加速されません。
データ転送についても少し拡張することもできますが、Danvilがそれに触れました。
小さな「s/wパス」で終了します。歴史的に、GLは、ハードウェアの特殊なケースが何であれ、仕様に取り組む必要がありました。つまり、h / wが特定のGL機能を処理していない場合は、それをエミュレートするか、ソフトウェアで完全に実装する必要がありました。多くの場合がありますが、多くの人を驚かせたのは、GLSLが現れ始めたときです。
GLSLシェーダーのコードサイズを推定する実際的な方法がなかったため、GLは任意のシェーダーの長さを有効と見なすことが決定されました。意味はかなり明確でした。任意の長さのシェーダーを使用できるh/wを実装するか(現時点では現実的ではありません)、as / wシェーダーエミュレーションを実装します(または、一部のベンダーが選択したように、単に準拠に失敗します)。したがって、フラグメントシェーダーでこの条件をトリガーした場合、少なくともその描画では、GPUがアイドル状態であっても、GL全体がCPUで実行される可能性があります。