タグ付けされた質問 「compute-shader」

3
コンピューティングシェーダーは、画像フィルタリングのピクセルシェーダーよりも効率的ですか?
ブラー、SSAO、ブルームなどの画像フィルタリング操作は、通常、ピクセルシェーダーと「収集」操作を使用して行われます。各ピクセルシェーダーの呼び出しは、隣接するピクセル値にアクセスするために多数のテクスチャフェッチを発行し、単一のピクセルの価値を計算します結果。このアプローチには、多くの冗長なフェッチが行われるという理論上の非効率があります。近くのシェーダー呼び出しは、同じテクセルの多くを再フェッチします。 別の方法は、計算シェーダーを使用することです。これらには、シェーダー呼び出しのグループ全体で少量のメモリを共有できるという潜在的な利点があります。たとえば、各呼び出しで1つのテクセルをフェッチして共有メモリに保存し、そこから結果を計算できます。これは、高速かもしれませんし、そうでないかもしれません。 質問は、どのような状況下で(実際に)コンピューティングシェーダーメソッドがピクセルシェーダーメソッドよりも実際に高速であるかということです。カーネルのサイズ、どんな種類のフィルタリング操作などに依存しますか?明らかに、答えはGPUのモデルによって異なりますが、一般的な傾向があるかどうか聞いてみたいと思います。

1
GPUプログラミングで作業効率が望ましいのはなぜですか?
私は、CUDAで並列スキャンを実行する方法に関する次の記事を読んでいます。 https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch39.html この記事では、スキャンを「作業効率」にすることに重点が置かれています。言い換えれば、GPUアルゴリズムはCPUアルゴリズムO(n)よりも多くの追加を実行するべきではありません。著者は2つのアルゴリズムを提示します。1つはO(nlogn)の追加を行う「ナイーブ」アルゴリズムで、もう1つは「作業効率」と考えるアルゴリズムです。ただし、作業効率の良いアルゴリズムでは、ループの繰り返しが2倍になります。 私の理解では、GPUは単純に巨大なSIMDプロセッサであり、ロックステップで動作するはずです。「作業効率の良い」アルゴリズムで2倍のループを実行すると、多くのスレッドがアイドル状態になり、長期的にはパフォーマンスが低下することを意味するようです。私は何が欠けていますか?

1
連続したOpenGL Compute Shader呼び出しの同期
特定の順序で実行する必要があり、出力が以前の入力に依存するいくつかの計算シェーダーがあります。理想的には、クライアント側のバッファーをコピーしてGPUですべての作業を行う必要はありません。 私はコンパイルとリンクとして2つのコンピュートシェーダ持って考えてみましょうprogram_oneとしますprogram_two。GL_SHADER_STORAGE_BUFFERによって書き込まれprogram_one、読み取られるデータを含むを持っているとしますprogram_two。次のことができますか? glUseProgram(program_one); glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer); glDispatchCompute(16, 16, 1); glUseProgram(program_two); glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer); glDispatchCompute(16, 16, 1); 最初の計算シェーダーのすべての呼び出しが、2番目の呼び出しの前に完了することが保証されていますか(読み取りと書き込みの間のデータの競合を回避するためbuffer)?そうでない場合、どのようにそれらを同期しますか?

1
GPUで共有頂点法線を作成する
私は、CPUからOpenGLコンピューティングシェーダーへのマーチングキューブの実装の移植にほとんど成功しましたが、私はまだ法線に取り組んでおらず、そのための最善の方法を考えていません。 私の実装では特にバイナリ値フィールドを扱います(まだ距離推定器を持たない3Dフラクタル関数をモデル化しようとしているため)、勾配法と前方差分法は機能しません。動作する頂点を共有しました。私のCPU実装では、ここで説明するQuilezの方法を使用して、隣接する各頂点に面法線を蓄積します。 この実装を別のシェーダーに移植することもできますが、これで発生する問題は、必要なアトミックの膨大な数です。私たちはスカラー整数型でのみアトミックを使用でき、3つの符号付き整数を合計可能な方法で1にパックする方法を考えることができないので、シェーダー呼び出しごとに3軸* 3頂点= 9アトミック追加を意味します。もちろん、それらはメモリ全体に分散されるため、1つのアトミックカウンターを9回ヒットするようなものではありませんが、それでもまだかなりのようです。 もう1つの方法は、ポリゴンごとのシェーダー呼び出しを実行して面の法線リストを作成し(おそらくこの方法でx10y10z10にパックすることができます)、次に頂点ごとのシェーダーで隣接する面の法線をすべて蓄積します。ただし、これは膨大なメモリを消費しますが、最悪の場合に対処するには、面インデックスのストレージスペースに頂点ごとに12 intが必要になります。また、特定の頂点に既に書き込まれている面の数を計算するためにアトミックに頼らずに、このストレージに書き込む方法の問題もあります。 誰でもこれを行う方法についてもっと良いアイデアがありますか?

1
シェーダーとCUDA / OpenCLの計算
だから私は最近、Compute Shaderについて学んだばかりで、CUDAやOpenCLで行う並列プログラミングと同じアイデアを私が見つけたものから、シェーダーパイプラインで見ていきます。 シーンに100万の立方体を描画したい場合は、どちらか一方または両方を使用する必要があります。両方をどのように分割して、GPUがシェーダーと別のプロセスの両方を同時に並列計算しないようにする場合

1
追加のコピーなしで、計算シェーダーを使用して圧縮テクスチャに書き込む
コンピューティングシェーダーを使用してOpenGLテクスチャを生成する最善の方法を理解しようとしています。これまでのところ、ピクセルバッファーオブジェクトは非ブロッキングCPU-> GPU転送に適していること、およびコンピューティングシェーダーは、どのようにバインドされているかに関係なく、バッファーを読み書きできることを確認しました。理想的には、できるだけ多くのコピーを避けたいと思います。つまり、GPUにバッファーを割り当て、圧縮されたテクスチャデータをGPUに書き込み、そのバッファーをシェーダーのテクスチャオブジェクトとして使用します。 現在、私のコードは次のようになります。 GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); glBufferStorage(GL_SHADER_STORAGE_BUFFER, tex_size_in_bytes, 0, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); // Bind buffer to resource in compute shader // execute compute shader glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer); glCompressedTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, tex_size_in_bytes, 0); これは正しいです?同期の保証についてもどこかで読みました。バッファオブジェクトからコピーする前に、コンピュートシェーダーが実行を完了させるために何を追加する必要がありますか?
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.