問題タブ [gpu-atomics]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
870 参照

cuda - グローバルなアトミック操作は Kepler でどのように実装されていますか? アトミックを使用するよりも gmem を使用すると、パフォーマンスが低下しました

Kepler でのグローバル アトミックの実装について知りたいです。

このコードを参照してください。

このために4行目を変更すると:

*dst -= 300000.0f;

性能が落ちる!これ以上スレッドがこの値に書き込むことはないため、変更は安全です (出力は同じです)。

アトミックを使用するカーネル: ~883us gmem を直接使用するカーネル: ~903us

私は何度か実行しましたが、常に変更に対して約 20us のペナルティが発生します。

更新 アトミックを使用しないストアは常にL2でミスを生成するようですが、アトミックバージョンは常にヒットを生成します...したがって、「アトミック」でフラグが立てられた(または何か)場所に書き込もうとすると、 L2 であり、gmem に別のリクエストを行います

0 投票する
2 に答える
2724 参照

cuda - 複数の変数を含むカスタム アトミック関数を実装するにはどうすればよいですか?

このアトミック関数を CUDA に実装したいと思います。

アトミック関数でこれを行うことができるとは思いません。いくつかの命令のために、いくつかのグローバル メモリ loc をロックダウンする必要があります。これを PTXAS (アセンブリ) コードで実装できますか?

0 投票する
1 に答える
779 参照

cuda - グローバルメモリ内の配列に対するCUDAアトミック操作

カーネルが基本的に次のことを行う CUDA プログラムがあります。

  • デカルト座標 (x_i,y_i) の n 個の点のリストを次元 dim_x * dim_y の平面に提供します。それに応じてカーネルを呼び出します。
  • この平面 (x_p,y_p) 上のすべての点について、n 個の点のそれぞれがそこに到達するのにかかる時間を数式で計算します。これらの n 個の点が特定の速度で移動しているとします。
  • これらの時間を t_0、t_1、...t_n の昇順で並べます。t_i の精度は 1 に設定されます。つまり、t'_i=2.3453 の場合、t_i=2.3 のみを使用します。
  • 時間が正規分布から生成されると仮定して、最も速い 3 つの時間をシミュレートして、それらの 3 つのポイントに最も早く到達した時間の割合を見つけます。したがって、ランダムな実験により、prob_0 = 0.76、prob_1 = 0.20、prob_2 = 0.04 と仮定します。t_0 は 3 つの中で最初に到達するため、ポイントの元のインデックス (時間の並べ替え前) も返します。idx_0 = 5 (整数) とします。
  • したがって、この平面上のすべての点について、ペア (prob,idx) を取得します。

これらのポイントの n/2 が 1 つの種類で、残りが他のポイントであるとします。生成されたサンプル画像は次のようになります。

最適化されていない

特に、時間の精度が 1 に設定されている場合、時間の一意の 3 つのタプル (t_0、t_1、t_2) の数は、全データ ポイント、つまり平面上のポイントの数のわずか 2.5% であることに気付きました。これは、ほとんどの場合、カーネルが以前のシミュレーションの値を使用するだけで無駄にシミュレートしていたことを意味していました。したがって、キーを時間の 3 タプル、値をインデックスと確率として持つ辞書を使用できます。私が知る限り、カーネル内で STL にアクセスできないため、サイズ 201000000 の float の配列を作成しました。この選択は、上位 3 回のいずれも 20 秒を超えなかったため、実験によるものでした。したがって、t_0 は {0.0,0.1,0.2,...,20.0} から任意の値を取ることができるため、201 の選択肢があります。次のような辞書のキーを作成できます

  • キー = t_o * 10^6 + t_1 * 10^3 + t_2

値に関する限り、(prob+idx) のようにすることができます。idx は整数であり、0.0<=prob<=1.0 であるため、後でこれらの値の両方を取得できます。

  • prob=dict[key]-floor(dict[key])
  • idx = フロア (dict[キー])

だから今、私のカーネルは次のようになります

結果は、ほとんどの点で元のプログラムと非常に似ていますが、一部は間違っています。

最適化されているが正しくない

これは競合状態によるものだと確信しています。dict がすべてゼロで初期化されていることに注意してください。基本的な考え方は、dict の特定の場所でデータ構造を「複数回書き込みを一度に読み取る」ようにすることです。

大量のメモリを割り当てるよりも、この問題を解決するためのより最適化された方法があるかもしれないことは承知しています。その場合はお知らせください。しかし、この特定のソリューションが失敗する理由を本当に理解したいと思います。特に、この設定でatomicAddを使用する方法を知りたいです。私はそれを使用するのに失敗しました。

0 投票する
1 に答える
846 参照

concurrency - CUDA アトミック操作と同時カーネル起動

現在、複数のストリームを使用して同時に起動される複数のカーネルを使用する GPU ベースのプログラムを開発しています。

私のアプリケーションでは、複数のカーネルがキュー/スタックにアクセスする必要があり、アトミック操作を使用する予定です。

しかし、同時に起動された複数のカーネル間でアトミック操作が機能するかどうかはわかりません。GPU でのアトミック操作の正確なメカニズムを知っている人、またはこの問題の経験がある人を助けてください。

0 投票する
1 に答える
3446 参照

cuda - Cuda アトミック ロック: スレッドの順番

セクションを批判的に実行する必要があるコードがあります。そのコードにロックを使用して、カーネルの各スレッド (ブロックごとに 1 つのスレッドで設定) がそのコードをアトミ​​ックに実行するようにしています。スレッドの順序は私を悩ませているものです-0から10までのインデックスに従って(または実際にはblockIdxの順序で)時系列でスレッドを実行する必要があります(5、8、3などのランダムではなく) 0、...など)。それは可能ですか?

コード例を次に示します。

次の結果が得られます。

これらのインデックスを 0 から開始し、時系列で 9 まで実行するようにします。

これを達成するためにロックを変更する方法の 1 つは、次のとおりです。

次に、引数としてインデックスを渡してロックを初期化します。

しかし、これは私のPCを失速させます...おそらく明らかな何かが欠けています。

誰かが助けることができれば、私はそれを感謝します!

ありがとう!!!

0 投票する
2 に答える
1470 参照

cuda - CUDA でアトミック ロードを行う方法

私の質問は、CUDA でアトミック ロードを行う方法です。アトミック交換は、アトミックストアをエミュレートできます。同様の方法でアトミック ロードを安価にエミュレートできますか? 0 のアトミック add を使用してコンテンツをアトミックにロードできますが、読み取りのみではなくアトミックな読み取り-変更-書き込みを行うため、コストがかかると思います。

0 投票する
2 に答える
252 参照

cuda - CUDA で同期する複数の変数

私のプログラムには、「aaaa」「bbbb」「cccc」などの 4 バイト文字列がたくさんあります... crc チェックに合格する特定の文字列を収集する必要があります。

文字列が crc チェックを通過できる可能性はほとんどないため、すべての結果を保持するために非常に大きなバッファーを使用したくありません。入力と同じように、結果を 1 つずつ連結することを好みます。たとえば、入力が「aaaabbbbcccc」で、「bbbb」が crc チェックに合格しない場合、出力文字列は「aaaacccc」で、output_count は 2 である必要があります。

コードは次のようになります。

明らかに、メモリ コピーはスレッド セーフではありません。atomicAdd 関数を ++ 操作に使用できることはわかっていますが、output と output_count の両方をスレッド セーフにする方法はありますか?