1

私は現在 OpenCL カーネルを作成しています (ただし、CUDA では同じになると思います)。現在、NVidia GPU の最適化を試みています。

現在、カーネルで 63 個のレジスタを使用しています。このカーネルは非常に大きいため、すべての GPU レジスタを使用しています。私はいくつかの方法を探しています:

1)どの変数がレジスタにあり、どの変数がグローバルメモリにあるかを確認します(十分なレジスタがない場合、コンパイラが変数をグローバルメモリに保存しているように見えるため)。

2)どの変数がより重要であるか(またはレジスタにある必要があるか)を指定する方法はありますか?存在するがあまり使用されていないいくつかの変数を使用しているためです。優先する方法は?

すでにすべてのレジスタを使用している場合、他の最適化戦略はありますか?

ところで: PTX コードを読み取ってすべての「.reg」キーワードを検索しようとしましたが、問題は PTX が読み取れないことです。コード内のどの変数にどのレジスタが使用されているかわかりません。連絡を取る方法が見つかりません!

ありがとう

4

3 に答える 3

3

(1) レジスタスピルと呼ばれます。SASSアセンブリを調べる以外に、どの変数がこぼれるかを見つける方法はないと思います。OpenCL は最初に PTX にコンパイルされます。これは、無限の数のレジスタ (スピルなし) を持つ仮想マシンです。詳細については、NVIDIA のプレゼンテーションLocal Memory and Register Spillingを参照してください。

(2)volatileレジスタに保持したくない変数を宣言するときに、キーワードを使用してみることができます。volatileコンパイラは、操作間で変数をレジスタに保持するのではなく、変数をメモリにプッシュするように強制されます。

于 2012-10-04T14:12:49.450 に答える
2

どの変数がレジスタにあり、どの変数がグローバル メモリにあるかを確認する

このため、私はそれを確認する方法を知りませんが、

どの変数がより重要かを指定する方法はありますか

レジスタをこぼしたことがわかったときに使用する1つのトリック(レジスタがないため、またはローカル変数で動的インデックスを使用する必要がある場合、これは悪いことです)は、それほど重要ではないと思うものを明示的に格納することです。ローカルメモリ (CUDA では「共有」と呼ばれる)

例:

uint16 somedata;

後:

__local uint16 somedata[WG_SIZE]; // or __local uint someadata[16];

ただし、ローカル メモリの使用量が大幅に増加すると、飛行中の波面の数が少なくなるため、ペナルティが発生するリスクがあることに注意してください (つまり、占有率が低くなる可能性があります)。

お役に立てれば。

于 2013-01-05T15:43:10.733 に答える
1

コードを見なくても、レジスタの使用を「強制」しようとする 1 つの方法は、限られた範囲でローカル コピーを使用することです。コードの特定の部分で、一部の変数のみがアクセスされる場合があります。次に、スコープで新しい変数を宣言し、これらを集中的に使用できます。保証はありませんが、時々役立つことはわかっています。

int a, b, d;
double x,y;

...

{
     int ra = a;     // copy into new variables more likely to be kept in registers
     double rx = x;

     ... use rx and ra ...

     a = ra;
     b = rx;       // copy back.
}

...
于 2012-10-05T07:18:35.593 に答える