3

「SIMT」アーキテクチャの概念と設計のいくつかは、私にはまだ不明です。

多くのスレッドがロックステップで実行される可能性があるため、私が見て読んだことから、分岐コード パスと if() を完全に使用するのはかなり悪い考えです。では、それは正確には何を意味するのでしょうか。次のようなものはどうですか:

kernel void foo(..., int flag)
{
    if (flag)
        DO_STUFF
    else
        DO_SOMETHING_ELSE
}

パラメータ「フラグ」はすべてのワークユニットで同じであり、すべてのワークユニットで同じ分岐が取られます。では、GPU はすべてのコードを実行し、それにもかかわらずすべてをシリアライズし、基本的にまだ取られていないブランチを取るのでしょうか? それとも、もう少し賢く、すべてのスレッドが取られた分岐に同意する限り、取られた分岐のみを実行しますか? ここでは常にそうです。

つまり、シリアル化は常に行われますか、それとも必要な場合にのみ行われますか? 愚かな質問で申し訳ありません。;)

4

3 に答える 3

3

いいえ、常に起こるわけではありません。両方のブランチの実行は、ローカル ワーク グループ内のスレッド間で条件が一貫していない場合にのみ発生します。つまり、ローカル ワーク グループ内のワーク アイテム間で条件が異なる値に評価される場合、現世代の GPU は両方のブランチを実行しますが、正しいブランチのみを実行します。値を書き込み、副作用があります。

したがって、コヒーレンシを維持することは、GPU ブランチでのパフォーマンスにとって不可欠です。

于 2010-08-22T16:40:08.357 に答える
1

atiについてはわかりませんが、nvidiaについては賢いです。ワープのすべてのスレッドが同じように進む場合、シリアライゼーションはありません。

于 2010-08-22T16:50:09.140 に答える
1

あなたの例では、フラグはすべての作業項目に対して同じ値を持つため、優れたコンパイラはすべての作業項目を同じ方向に取るコードを生成します。

しかし、次のケースを考えてみてください。

kernel void foo(..., int *buffer)
{
    if (buffer[get_global_id(0)])
        DO_STUFF
    else
        DO_SOMETHING_ELSE
}

ここでは、すべての作業項目が同じパスをたどるとは限らないため、シリアライゼーションまたは制御フローの除去が必要です。

于 2010-08-22T17:00:14.753 に答える