29

これを読んだとき、私はショックを受けました(OpenGL wikiから):

glTranslate、glRotate、glScale

これらのハードウェアは高速化されていますか?

いいえ、これを実行する既知のGPUはありません。ドライバーはCPUでマトリックスを計算し、それをGPUにアップロードします。

他のすべてのマトリックス操作もCPUで実行されます:glPushMatrix、glPopMatrix、glLoadIdentity、glFrustum、glOrtho。

これが、これらの機能がGL3.0で非推奨と見なされる理由です。独自の数学ライブラリを用意し、独自のマトリックスを作成し、マトリックスをシェーダーにアップロードする必要があります。

非常長い間、私はほとんどのOpenGL関数がGPUを使用して計算を行うと思っていました。これが一般的な誤解であるかどうかはわかりませんが、しばらく考えてみると、これは理にかなっています。古いOpenGL関数(2.x以前)は、状態スイッチが多すぎるため、実際のアプリケーションには実際には適していません。

これにより、おそらく、多くのOpenGL関数がGPUをまったく使用していないことに気付きます。

したがって、問題は次のとおりです。

GPUを使用しないOpenGL関数呼び出しはどれですか?

上記の質問に対する答えを知っていると、OpenGLでより優れたプログラマーになるのに役立つと思います。あなたの洞察のいくつかを共有してください。

編集:

この質問は簡単に最適化レベルにつながることを私は知っています。それは良いことですが、それはこの質問の意図ではありません。

GPUを使用しない特定の一般的な実装(AshleysBrainが提案したように、nVidia / ATI、および場合によってはOSに依存する)のGL関数のセットを誰かが知っているなら、それが私が求めているものです!

もっともらしい最適化ガイドは後で来ます。このトピックでは、関数に焦点を当てましょう。

Edit2:

このトピックは、行列変換がどのように機能するかについてではありません。そのための他の トピックがあります。

4

5 に答える 5

41

少年、これは大きなテーマです。

まず、明らかなことから始めましょう。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で実行される可能性があります。

于 2010-04-26T20:52:21.520 に答える
10

問題はおそらく「どの機能が予想外に長いCPU時間を消費するのか」ということです。

投影と表示のためにマトリックススタックを維持することは、GPUがCPUよりもうまく処理できることではありません(逆に...)。別の例は、シェーダーのコンパイルです。なぜこれをGPUで実行する必要があるのですか?パーサー、コンパイラーなどがあります。これらは、C++コンパイラーのような通常のCPUプログラムです。

glReadPixelsたとえば、制限されたバスを介してデータをホスト(= CPU)メモリからデバイス(= GPU)メモリにコピーできるため、「危険な」関数呼び出しが発生する可能性があります。このカテゴリには、glTexImage_Dまたはのような関数もありますglBufferData

したがって、一般的に言って、OpenGL呼び出しが消費するCPU時間を知りたい場合は、その機能を理解するようにしてください。また、ホストからデバイスにデータをコピーしたり、データをコピーしたりするすべての機能に注意してください。

于 2010-04-26T13:06:17.153 に答える
8

通常、操作が何かごとの場合、GPUで発生します。例は実際の変換です-これは頂点ごとに1回行われます。一方、大規模な操作ごとに1回だけ発生する場合は、CPU上にあります。たとえば、変換行列の作成は、オブジェクトの状態が変化するたびに1回だけ、またはフレームごとに1回だけ実行されます。

これは単なる一般的な答えであり、一部の機能は逆に発生します。また、実装に依存します。ただし、通常、プログラマーであるあなたにとっては問題ではありません。ゲームシムなどを行っていないときにGPUが機能するのに十分な時間を与えるか、スレッドモデルがしっかりしている限り、それほど心配する必要はありません。

@GPUへのデータの送信:私が知る限り(Direct3Dのみを使用)、すべてシェーダー内で実行されます。これがシェーダーの目的です。

于 2010-04-26T17:53:17.447 に答える
5

glTranslate、glRotate、およびglScaleは、現在アクティブな変換行列を変更します。もちろんこれはCPUの動作です。モデルビューとプロジェクションマトリックスは、レンダリングコマンドを発行するときにGPUが頂点を変換する方法を説明しているだけです。

たとえば、glTranslateを呼び出すと、まだ何も変換されません。現在の投影とモデルビューの行列をレンダリングする前に(MVP =投影*モデルビュー)、この単一の行列がGPUにコピーされ、GPUが各頂点に対して行列*頂点の乗算( "T&L")を実行します。したがって、頂点の変換/スケーリング/投影はGPUによって行われます。

また、これらの関数をどこかの内部ループで使用しない場合は、パフォーマンスについて心配する必要はありません。glTranslateの結果、3つの追加が行われます。glScaleとglRotateはもう少し複雑です。

私のアドバイスは、線形代数についてもう少し学ぶべきだということです。これは、3DAPIを操作するために不可欠です。

于 2010-04-26T14:56:11.397 に答える
2

OpenGLにはソフトウェアでレンダリングされた実装があるため、GPUでOpenGL関数が実行されない可能性があります。ハードウェアで特定のレンダリング状態をサポートしないハードウェアもあるため、特定の状態を設定してソフトウェアレンダリングに切り替えると、GPUで何も実行されません(そこにある場合でも)。したがって、「GPUアクセラレーション機能」と「非GPUアクセラレーション機能」の間に明確な違いはないと思います。

安全を期すために、物事をできるだけシンプルにしてください。頂点を使用した単純なレンダリングとZバッファリングなどの基本機能は、ハードウェアアクセラレーションである可能性が高いため、最小限の状態変更でそれに固執できれば、ハードウェアアクセラレーションを維持できる可能性が高くなります。これは、ハードウェアアクセラレーションによるレンダリングのパフォーマンスを最大化する方法でもあります。グラフィックカードは、1つの状態を維持し、多数の頂点をクランチするのが好きです。

于 2010-04-26T13:39:46.133 に答える