計算シェーダーとパイプラインシェーダーによるアルゴリズムの実装


10

DirectXとOpenGLの両方のコンピューティングシェーダーが利用可能になったことで、ラスタライズパイプラインを経由せずに多くのアルゴリズムを実装し、代わりにGPUで汎用コンピューティングを使用して問題を解決できるようになりました。

一部のアルゴリズムでは、これは本質的にラスター化ベースではないため、これは直感的な標準的な解決策になり、ラスター化ベースのシェーダーはGPUパワーを活用するための回避策のように見えました(簡単な例:ノイズテクスチャを作成します。ここでクワッドをラスター化する必要はありません) )。

両方の方法で実装できるアルゴリズムが与えられた場合、通常のルートを使用する場合と比較して、計算シェーダーを使用する場合に比べて一般的な(潜在的な)パフォーマンス上の利点はありますか?注意が必要な欠点はありますか(たとえば、実行時にシェーダーの計算を切り替えるために、ある種の異常なオーバーヘッドがあります)?

2つを選択するときに考慮すべき他の利点または欠点はおそらくありますか?


パフォーマンスタグが実際に関連している場合は、Marco FratarcangeliのGame Engine Gems "Cloth Simulation"の記事からこの動画を視聴することを検討してください:youtube.com/watch ?v=anNClcux4JQ 。コメントを読んでぎこちないことがわかります。GLSL/シェーダーベースの実装は、CUDAまたはOpenCLを使用するよりも高速でした(後者は、現時点でのドライバーサポートが不十分なため2010)。違いを生む特定の低レベルの違いがあります。
teodron 2013年

@teodron GPU Gemsがなく、ソースコードが見つかりません。著者は実際にGLSL頂点+ピクセルシェーダーを使用しましたか、それともGLSL計算シェーダーを使用しましたか?
TravisG 2013年

はい!CUDAが登場する前は、コミュニティがGPGPU機能を実装する方法でした。ここで1は、純粋なGLSL ORクーダを使用してちょうどことを達成することができる方法を参照するにはOpenClothへのリンクです:code.google.com/p/opencloth/source/browse/trunk/...
teodron

回答:


7

コンピューティングシェーダー/ GPGPUアプローチを直接利用する場合、正しい答えはありません。これは、実装しているアルゴリズムのタイプに大きく依存します。コンピュートシェーダーとCUDA / OpenCLは、いくつかの制限を克服するためのより一般的なアプローチですその古いシェーディング言語のハック。あなたが得る最も重要な利点:

  • 空間情報へのアクセス。古いGLSLハック(まあ、それはハックでした!)では、テクスチャ座標を使用するため、隣接するフラグメントに関する情報はほとんど提供されません。コンピューティングシェーダー/ CUDA / OpenCLでは、空間情報へのアクセスがはるかに柔軟になり、順序付けされていないテクスチャー/バッファーアクセスを使用して、GPUにヒストグラム等化のようなアルゴリズムを実装できるようになりました。
  • スレッドの同期とアトミックを提供します。
  • 計算スペース:古いGLSLハックは、頂点/フラグメント計算スペースをシェーダーにハードワイヤーします。フラグメントシェーダーはフラグメントの数で実行され、頂点シェーダーは頂点の数で実行されます。コンピュートシェーダーでは、独自のスペースを定義します。
  • スケーラビリティ:同じSMで実行する必要がある古いGLSLシェーダーとは異なり、コンピュートシェーダー/ CUDA / OpenCLは、使用可能なGPU SM(ストリーミングマルチプロセッサー)の数までスケールアップできます。(ネイサンリードのコメントに基づいて、彼はそうではないと言います。シェーダーはコンピュートシェーダーと同じようにスケールアップする必要があります。ドキュメントを確認する必要がありますが、まだわかりません)。
  • コンテキストの切り替え:いくつかのコンテキストの切り替えが必要ですが、それはアプリケーションによって異なるので、アプリケーションのプロファイルを作成することをお勧めします。

まあで私の意見あなたは、特定のアルゴリズムがより適切であっても、コンピュートシェーダのルートを移動したい場合は、あなたが考慮に入れる必要がある特定の考慮事項があります。

  1. ハードウェアと下位互換性。コンピュートシェーダーは新しいハードウェアでのみ使用でき、商用製品(ゲームなど)を使用する場合、多くのユーザーが製品を実行できない可能性があることを期待する必要があります。
  2. あなたは通常、GPU / CPUアーキテクチャの余分な知識必要あなたがいることを、並列プログラミングやマルチスレッド(例えばメモリ共有、メモリ一貫性、スレッド同期、アトミックとパフォーマンスに、それの効果)を通常使用する必要はありません通常のシェーダrounteを。
  3. 学習リソース、経験から、通常のシェーダールートよりもコンピュートシェーダー、OpenCL、CUDA(OpenGL相互運用性も提供)の学習リソースははるかに少なくなります。
  4. デバッグツールは、適切なデバッグが欠如しているため、ツールの開発はほとんどのシェーダーよりもはるかに困難になる可能性があり、少なくともシェーダーは視覚的にデバッグできます。
  5. コンピューティングシェーダーは、他のシェーダーの同じアルゴリズムよりも優れたパフォーマンスを提供することを期待しています。グラフィックレンダリングの余分な手順を回避するように設計されているため、ポイント2からのことを考慮して正しく行われた場合。しかし、私の主張を裏付ける具体的な証拠はありません。
  6. そのルートを使用する場合は、CUPG / OpenCL for GPGPUも検討する必要があります。

それでも、それが将来に向けて素晴らしいことであり、素晴らしい学習経験になると確信しています。幸運を!


私はOPがこれを求めていると思う:なぜ純粋なGLSLシェーダーを使用して問題を解決するのか、それをCUDAでコーディングするのか?著者がそれを行う布シミュレーションに関するゲームプログラミング宝石の記事があります。そして、GLSLハックな古い方法は、パフォーマンスの点でCUDAの方法よりも優れています。理由がわかれば、おそらく指摘する必要があります。
teodron 2013年

2
私はあなたのスケーラビリティポイントが正しいとは思いません-頂点シェーダーとフラグメントシェーダーは、コンピューティングシェーダーと同じようにGPU全体をスケーリングできます。スレッドグループのサイズと共有メモリの使用により、一度に実行できるシェーダースレッドの数に追加の制限が課される可能性があるため、実際にシェーダーを計算することは、スケーリングがより困難になる可能性があります。
Nathan Reed

2
また、テクスチャを入力している場合(ノイズの生成やその他の手続き型アルゴリズムの実行など)、私の経験では、各ピクセルで数式を評価するだけであれば、フラグメントシェーダーの方が計算シェーダーよりも高速です。これは、フラグメントの順序が内部のタイル/スウィズルされたピクセルの順序と一致するため、この順序を認識しない計算シェーダーよりもメモリの局所性が向上するためと考えられます。計算シェーダーは、共有メモリーなどの特別な機能を使用して、フラグメントシェーダーに比べて速度を大幅に向上できる場合にのみ高速になります。
Nathan Reed

2
はい、最後のコメント。:)グラフィックからコンピューティングへ、またはその逆に移行する場合、現在のほとんどのGPUには、何らかのコンテキストスイッチまたはモードスイッチがあると思います。したがって、いくつかのグラフィックシェーダーを実行してから、コンピュートシェーダーをディスパッチし、さらにいくつかのグラフィックシェーダーを実行するなどの場合、切り替えを切り替えるとパフォーマンスが低下します。これはプロファイリングする必要があることですが、特定の場合にグラフィックシェーダーを使用するもう1つの理由かもしれません。
Nathan Reed

@NathanReedコメントに感謝私は私の答えを更新します。
concept3d 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.