2

より大きなコードの一部として、多数の ODE (1000 以上) を並列に統合する CUDA RK4 ソルバーがあります。この操作の 1 つのステップは、各方程式 (またはデータ要素) ごとに異なる「xdot」を計算することです。今のところ、カーネル内の各データ要素の値を計算するためのスイッチケース分岐セットアップがあります。異なるスレッドはすべて同じ 3 ~ 6 個のデータ要素を使用して出力を計算しますが、方法は異なります。たとえば、スレッド 1 の場合、次のようになります。

xdot = データ[0]*データ[0] + データ[1];

一方、スレッド 2 の場合は、

xdot = -2*data[0] + data[2];

等々。したがって、100 個のデータ要素がある場合、実行パスはそれぞれ異なります。

このようなシナリオでスレッド発散のペナルティを回避/減少させる方法はありますか? ブロックごとに 1 つのスレッドのみを実行することは役に立ちますか?

4

1 に答える 1

3

ブロックごとに 1 つのスレッドを実行すると、起動する 1 つのワープで 31/32 スレッドが無効になり、多くのサイクルとレイテンシを隠す機会が無駄になります。あなたのコードがどれだけ分岐分岐ペナルティを被ったとしても、私は決してお勧めしません。

あなたのアプリケーションは、基本的な CUDA プログラミング パラダイムにかなり近いように思えますが、分岐分岐のペナルティを回避するためにできることはあまりありません。状況をわずかに改善できるアプローチの 1 つは、各方程式の式の事前分析を実行し、共通の算術用語を持つものをグループ化することです。最近のハードウェアは多数のカーネルを同時に実行できるため、単一の大きなカーネルではなく、類似項を共有する計算を異なるカーネルにグループ化し、それらを同時に起動する方が有益な場合があります。CUDA は C++ テンプレートをサポートしています。これは、比較的狭いベースから多くのカーネル コードを生成し、多くのロジックを静的に評価できるようにするための優れた方法であり、コンパイラに役立ちます。しかし、しないでください

于 2013-07-20T09:52:57.227 に答える