1

スレッドごとに小さな連想配列を維持する必要があるCUDAカーネルを書いています。小さいとは、最悪の場合に最大8つの要素を意味し、予想されるエントリ数は2程度です。だから何も派手ではありません。キーの配列と値の配列だけであり、インデックス付けと挿入は、上記の配列のループによって行われます。

今、私はスレッドローカルメモリを使ってこれを行います。つまり、識別子[サイズ]です。ここで、sizeはコンパイル時定数です。ある状況ではこのメモリはオフチップに保存され、ある状況ではオンチップに保存されると聞いたことがあります。明らかに、私はすべての状況下で後者が欲しいです。私は、共有メモリのブロックを使用してこれを実現できることを理解しています。共有メモリでは、各スレッドを独自のプライベートブロックで動作させます。でも本当に?私はスレッド間で何も共有したくありません、そしてそれは恐ろしい恨みでしょう。

この記憶がどこに行くかについての規則は正確には何ですか?nvidiaから単語が見つからないようです。記録のために、私はCUDA5を使用し、Keplerをターゲットにしています。

4

1 に答える 1

4

ローカル変数は、レジスタに格納されるか、(計算機能> = 2.0のためにキャッシュされます)オフチップメモリ​​に格納されます。

レジスタは、すべての配列インデックスが一定であり、コンパイル時に決定できる場合にのみ配列に使用されます。これは、アーキテクチャには実行時にレジスタへのインデックス付きアクセスの手段がないためです。

あなたの場合、キーの数はレジスターを使用するのに十分少ないかもしれません(そしてレジスターの圧力の増加を許容します)。配列アクセスのすべてのループを展開して、コンパイラがキーをレジスタに配置できるようにし、cuobjdump -sass実際にそれが行われるかどうかを確認するために使用します。

レジスターを使いたくない場合は、スレッドごとのオフセットを持つ共有メモリーを選択できます(ただし、スレッドごとのインデックスを共有メモリーに保持するために使用される追加のレジスターが、使用するキーの数を上回らないことを確認してください)あなたが言ったように、または何もせずにオフチップの「ローカル」メモリ(実際には異なるアドレス指定スキームを持つ「グローバル」メモリ)を使用して、キャッシュが機能することを期待します。

キャッシュがキーと値を保持することを望み、共有メモリをあまり使用しない場合は、を使用してデフォルトの16kB/48kB分割よりも48kBキャッシュ/16kB共有メモリ設定を選択すると便利な場合がありますcudaDeviceSetCacheConfig()

于 2012-09-20T11:40:23.170 に答える