2011-07-13 9 views
7

GPUがどのように同期を実行するかについていくつか質問があります。 私が知っているように、ワープがバリアに遭遇したとき(OpenCLにあると仮定して)、同じグループの他のワープがまだ存在していないことを知っています。だからそれは待たなければならない。しかし、そのワープは待ち時間の間に正確に何をするのでしょうか? まだアクティブなワープですか?それとも、何らかのヌル操作をしますか?GPUの同期

私が気づいたように、カーネルで同期が取れれば、命令数が増えます。私はこの増分の原因が何であるか疑問に思います。同期は多くの小さなGPU命令に分割されていますか?アイドルワープがいくつか余分な命令を実行するためですか?

最後に、同期なしのものと比較して、同期によって追加されたコストが(ワークグループ(スレッドブロック)のワープ数によって影響を受けるとしますか? ありがとう

答えて

7

アクティブワープはSMに常駐しています。つまり、すべてのリソース(レジスタなど)が割り当てられており、スケジューリング可能な場合は実行可能です。ワープが同じスレッドブロック/ワーキンググループ内の他のワープより先にバリアに到達すると、ワープはまだアクティブになります(まだSMに常駐しており、すべてのレジスタは有効です)。しかし、命令は実行されません。予定される準備ができていません。

バリアの挿入は、実行をストールするだけでなく、コンパイラのバリアとしても機能します。このため、バリアの目的が無効になる可能性があるため、コンパイラはバリア全体でほとんどの最適化を実行できません。これは、より多くの命令が表示される最も可能性の高い理由です。このバリヤーがなければ、コンパイラーはより多くの最適化を実行できます。

バリアのコストはコードの処理内容に大きく依存しますが、すべてのワープがすべて有効になってから、すべての作業が再開されるまでにバブルが発生するため、非常に大きなスレッドブロック/ work-groupではもちろん、小さなブロックよりも大きなバブルが潜在的に存在します。バブルの影響はコードに依存します。コードがメモリに非常に拘束されている場合、バリアが隠されていた可能性があるメモリのレイテンシを公開しますが、よりバランスが取れていればそれほど顕著な効果はありません。

これは、メモリに非常に拘束されたカーネルでは、より多くの小さなブロックを起動して、1つのブロックがバリア上でバブリングしているときに他のブロックを実行できるようにする方がよいことを意味します。その結果、占有量が増加することを保証し、ブロック共有メモリを使用してスレッド間でデータを共有する場合は、トレードオフが必要です。

+0

詳細な回答ありがとうございます。あなたが知っているいくつかの文書を共有することができればうれしいでしょう。私は私の研究を引用したいと思います。メモリバインドカーネルがメモリレイテンシを公開する理由をもっと説明できますか?私が今理解しているように、ある計算によって隠されていたと思われる同期の近くのメモリ要求(同期の前に現れる)は、データが到着するまで停止するでしょう。それが正しいか?一方、カーネルがmem-boundでない場合、同期には何が公開されますか?命令パイプライン待ち時間? (相違はないと思われますが、それはすべて、相違して何をするのでしょうか?) – Zk1001