web-dev-qa-db-ja.com

OpenGLとOpenCL、どちらを選択するのか、なぜですか?

計算のためにGLSLを使用してOpenGLよりも優れたOpenCLを選択する機能は何ですか?グラフィック関連の用語と非実用的なデータ型にもかかわらず、OpenGLに実際の警告はありますか?

たとえば、並列関数の評価は、他のテクスチャを使用してテクスチャにレンダリングすることにより実行できます。操作を削減するには、より小さなテクスチャに繰り返しレンダリングします。一方、ランダムな書き込みアクセスは、効率的な方法では不可能です(行う唯一の方法は、テクスチャ駆動の頂点データによって三角形をレンダリングすることです)。これはOpenCLで可能ですか? OpenGLでは不可能な他に何が可能ですか?

70
dronus

OpenCLは、コンピューティング専用に作成されています。 OpenGLを使用して科学計算を行う場合、計算を進めるために、計算の問題をグラフィックスコンテキストにマップする方法を常に考える必要があります(つまり、テクスチャや三角形などの幾何学的なプリミティブについて話します)。

OpenCLでは、メモリバッファ上の計算カーネルを使用して計算を定式化するだけで、準備は完了です。これは実際には大きな勝利です(両方のバリエーションを考えて実装したという観点から言えます)。

メモリアクセスパターンは同じですが(計算はまだGPUで行われていますが、最近ではGPUの柔軟性が向上しています)。

しかし、翻訳方法について頭を痛めずに十数個の並列「CPU」を使用するよりも、他に何を期待しますか? (愚かな例)三角形から四角形へのフーリエ変換...?

56
cli_hlt

これまでの回答で言及されていないものは、実行速度です。 IfアルゴリズムはOpenGLグラフィックスで表現できます(たとえば、分散書き込み、ローカルメモリ、ワークグループなどはありません)。これに関する私の具体的な経験は、AMD、nVidia、IMG、およびQualcomm GPUでイメージフィルター(収集)カーネルを実行したことです。 OpenGLの実装は、筋金入りのOpenCLカーネル最適化の後でも、常に高速で実行されます。 (さておき:これは、グラフィックス指向のワークロードに合わせて特別に調整されたハードウェアとドライバーの長年によるものと思われます。)

私のアドバイスは、あなたの計算プログラムfeelsがグラフィックドメインにうまくマッピングされているなら、OpenGLを使用することです。そうでない場合、OpenCLはより一般的で、計算の問題を表現するのが簡単です。

言及する(または尋ねる)もう1つの点は、趣味で書くか(つまり、自分用)、商業的に書くか(つまり、他人に配布するか)です。 OpenGLはほぼすべての場所でサポートされていますが、OpenCLはモバイルデバイスでのサポートが完全に欠けているため、今後数年のうちにAndroidまたはiOSに登場する可能性は非常に低いです。単一のコードベースが目標である場合、OpenGLが強制される場合があります。

41
user2746401

GLSLを使用した計算にOpenGLよりも優れたOpenCLを選択する機能は何ですか?グラフィック関連の用語と非実用的なデータ型にもかかわらず、OpenGLに実際の警告はありますか?

はい:グラフィックスAPIです。したがって、そこで行うすべてのことは、それらの用語に沿って策定する必要があります。データを何らかの「レンダリング」形式としてパッケージ化する必要があります。属性、均一バッファ、およびテクスチャの観点からデータを処理する方法を理解する必要があります。

OpenGL 4.3およびOpenGL ES 3.1 compute shaders を使用すると、事態は少し混乱します。計算シェーダーは、OpenCL計算操作と同様の方法で、SSBO/Image Load/Storeを介してメモリにアクセスできます(ただし、OpenCLは実際のポインターを提供しますが、GLSLは提供しません)。 OpenGLとの相互運用もOpenCL/GL相互運用よりもはるかに高速です。

それでも、計算シェーダーは1つの事実を変更しません。OpenCL計算操作は、OpenGLの計算シェーダーとは異なるvery精度で動作します。 GLSLの浮動小数点精度の要件はそれほど厳密ではなく、OpenGL ESの要件はさらに厳密ではありません。したがって、計算で浮動小数点の精度が重要な場合、OpenGLは計算に必要なものを計算する最も効果的な方法ではありません。

また、OpenGLコンピューティングシェーダーには4.x対応のハードウェアが必要ですが、OpenCLははるかに低いハードウェアで実行できます。

さらに、レンダリングパイプラインを選択して計算を実行している場合、OpenGLドライバーは引き続きレンダリングを実行していると想定します。そのため、その仮定に基づいて最適化を決定します。絵を描いていると仮定して、シェーダーリソースの割り当てを最適化します。

たとえば、浮動小数点フレームバッファーにレンダリングしている場合、ドライバーはR11_G11_B10フレームバッファーを提供することを決定する場合があります。これは、アルファで何もしていないことを検出し、アルゴリズムが低い精度を許容できるためです。ただし、フレームバッファの代わりに image load/store を使用すると、この効果が得られる可能性ははるかに低くなります。

OpenCLはグラフィックスAPIではありません。それは計算APIです。

また、OpenCLでは、より多くのものにアクセスできます。 GLに関して暗黙のメモリレベルにアクセスできます。特定のメモリはスレッド間で共有できますが、GLの個別のシェーダーインスタンスは相互に直接影響を与えることはできません(イメージのロード/ストアの外部ですが、OpenCLはアクセスのないハードウェアで実行されますそれに)。

OpenGLは、ハードウェアが行っていることを抽象化の背後に隠します。 OpenCLは、何が起こっているかをほぼ正確に示します。

あなたはcanOpenGLを使用して任意の計算を行うことができます。ただし、want;完全に実行可能な代替案がある間ではありません。 OpenGLのComputeは、グラフィックスパイプラインにサービスを提供します。

onlyレンダリング以外のあらゆる種類の計算操作でOpenGLを選択する理由は、OpenCLを実行できないハードウェアをサポートするためです。現時点では、これには多くのモバイルハードウェアが含まれます。

22
Nicol Bolas

注目すべき機能の1つは書き込みの分散であり、もう1つは「Windows 7のスマートネス」の欠如です。おそらくご存知のように、Windows 7は、OpenGLが2秒間フラッシュしない場合、ディスプレイドライバーを強制終了します(正確な時間を特定しないでください。2秒だと思います)。長時間の操作がある場合、これは煩わしいかもしれません。

また、OpenCLは明らかにグラフィックカードよりもはるかに多様なハードウェアで動作し、「人工的な制約」のある厳格なグラフィック指向のパイプラインを持ちません。同時に複数のコマンドストリームを実行するのも簡単です(簡単です)。

12
Damon

現在、グラフィックスにはOpenGLの方が適していますが、これは永続的なものではありません。

OpenGLが最終的にOpenCLの拡張としてマージすることが実用的である可能性があります。 2つのプラットフォームは約80%同じですが、構文が異なり、ハードウェアのほぼ同じコンポーネントの命名法が異なります。つまり、2つの言語を学習し、2つのAPIを把握する必要があります。グラフィックドライバー開発者は、2つの別々のプラットフォーム用に開発する必要がなくなるため、マージを好むでしょう。これにより、ドライバーのデバッグのための時間とリソースが増えます。 ;)

考慮すべきもう1つの点は、OpenGLとOpenCLの起源が異なることです。OpenGLは、ネットワーク上の初期の固定パイプラインの時代に勢いを増し始め、技術の発展とともに徐々に追加され、廃止されました。 OpenCLは、いくつかの点で進化していますof OpenGLは、GPUの(計画外の)柔軟性が許容されるため、数値処理にOpenGLが使用され始めたという意味でOpenGLです。 「グラフィックスvsコンピューティング」は、実際にはより意味論的な議論です。どちらの場合も、可能な限り最高のパフォーマンスで数学演算をハードウェアに常にマップしようとしています。 Vanilla CLが使用しないGPUハードウェアの部分がありますが、そうすることで個別の拡張機能が維持されることはありません。

それでは、OpenGLはCLでどのように機能しますか?投機的に、三角形ラスタライザーは特別なCLタスクとしてキューに入れることができます。特別なGLSL関数をVanilla OpenCLに実装し、カーネルコンパイル中にドライバーによってハードウェアアクセラレーション命令にオーバーライドできます。ライブラリ拡張機能が提供されるまで、OpenCLでシェーダーを記述することは、苦痛を感じる経験ではありません。

一方を呼び出して他方よりも多くの機能を持たせることは、異なる命名法のもとで両方が同じ機能を80%獲得しているため、あまり意味がありません。グラフィックス処理isコンピューティングであるため、OpenCLはコンピューティング用に設計されているためグラフィックスに適さないと主張することは意味がありません。

9
user515655

もう1つの主な理由は、OpenGL\GLSLがグラフィックカードでのみサポートされていることです。マルチコアの使用はグラフィックスハードウェアの使用から始まりましたが、多くのハードウェアベンダーが計算用のマルチコアハードウェアプラットフォームに取り組んでいます。たとえば、Intels Knights Cornerを参照してください。

OpenGL\GLSLを使用して計算用のコードを開発すると、グラフィックカードではないハードウェアを使用できなくなります。

6
Tal Darom

OpenGL 4.5の時点で、これらはOpenCL 4.5にはない機能(OpenGL 4.5にはない機能です)(OpenGLにはない機能ですが、OpenCLにはない機能です):

イベント

より良いアトミック

ブロック

ワークグループ関数:work_group_allおよびwork_group_any work_group_broadcast:work_group_reduce work_group_inclusive/exclusive_scan

カーネルからカーネルをエンキューする

ポインター(ただし、GPUで実行している場合、これはおそらく重要ではありません)

OpenGLにはない数学関数(OpenGLで自分で作成できますが)

共有仮想メモリ

(その他)カーネルのコンパイラオプション

特定のGPU(またはそれ以外)の選択が簡単

GPUがない場合はCPUで実行できます

これらのニッチなハードウェアプラットフォーム(例:FGPA)のサポートの強化

一部の(すべての?)プラットフォームでは、計算を行うためにウィンドウ(およびそのコンテキストバインディング)を必要としません。

OpenCLを使用すると、計算の精度(これらのコンパイラオプションによるものを含む)を少しだけ制御できます。

上記の多くは、主にCPUとGPUの相互作用を向上させるためのものです。イベント、共有仮想メモリ、ポインター(ただし、これらは潜在的に他のものにも役立つ可能性があります)。

OpenGLは、ここで他の多くの投稿が行われたため、クライアントとサーバーのメモリのさまざまな領域に物事を分類する機能を獲得しました。 OpenGLはより優れたメモリバリアとアトミックサポートを備えており、GPU内のさまざまなレジスタに(OpenCLができるのとほぼ同程度まで)物を割り当てることができます。たとえば、OpenGLでローカル計算グループのレジスタを共有できます(AMD GPU LDS(ローカルデータ共有)のようなものを使用します(ただし、この特定の機能は、現時点ではOpenGL計算シェーダーでのみ動作します)。一部のプラットフォーム(オープンソースLinuxドライバーなど)。OpenGLは、より多くの固定機能ハードウェアにアクセスできます(他の回答が述べているように)時々、固定機能ハードウェアを回避できることもあります(例:Crytekは、デプスバッファー)固定機能ハードウェアはメモリを適切に管理でき(通常、GPUハードウェア会社で働いていない人よりもはるかに優れています)、ほとんどの場合、非常に優れています。 OpenGLの主要な固定機能領域の1つであるサポート。

Intels Knights Cornerは、それ自体を制御するx86 GPUであると主張します。また、テクスチャ関数を備えたOpenCL 2.0(実際にはOpenCLの下位バージョンにあります)は、user2746401が推奨するパフォーマンスとほぼ同じ程度に使用できると主張します。

4
afree100

OpenCL(2.0バージョン)は、システムのすべてのコンポーネントが他のシステムコンポーネントによって生成されたタスクを生成および消費できる、異種計算環境を記述しています。 CPUやGPU(など)の概念はもう必要ありません。ホストとデバイスだけが必要です。

OpenGLは、逆に、タスクプロデューサーであるCPUとタスクコンシューマーであるGPUに厳密に分割されています。柔軟性が低いとパフォーマンスが向上するため、それは悪くありません。 OpenGLは、より狭いスコープの機器です。

3

OpenCLが汎用計算用に設計されているのに対し、OpenGLはグラフィック用に設計されている「機能」。 GL(チューリング完全))では何でもできますが、ドライバーのハンドルをハンマーとして使用して釘を打ち込んでいます。

また、OpenCLはGPUだけでなく、CPUやさまざまな専用アクセラレーターでも実行できます。

2
Basil Marte

すでに存在する答えに加えて、OpenCL/CUDAは計算ドメインにより適合しているだけでなく、基盤となるハードウェアを過度に抽象化しません。この方法では、共有メモリや合体メモリアクセスなどの機能をより直接的に活用できます。そうしないと、シェーダーの実際の実装に埋もれてしまいます(必要に応じて、それ自体が特別なOpenCL/CUDAカーネルにすぎません)。

そのようなことから利益を得るには、カーネルが実行される特定のハードウェアについてもう少し知っておく必要がありますが、シェーダーを使用してそれらを明示的に考慮しないでください(完全に可能な場合でも)。

単純なレベル1 BLASルーチンよりも複雑な操作を行うと、OpenCL/CUDAの柔軟性と汎用性を確実に理解できます。

2
Christian Rau