次のように、カーネルで固定サイズの配列を設定する場合:
int my_array[100];
配列はどのメモリ空間に配置されますか?
特に、そのような配列が >= 2.0 デバイスのレジスタ ファイルまたは共有メモリに格納されるかどうか、およびその場合の要件は何かを調べたいと思います。
Fermi (およびおそらくそれ以前のアーキテクチャ) の場合、配列をレジスタ ファイルに格納するには、次の条件を満たす必要があります。
(1) の理由は、レジスタ インデックスが SASS 命令内で直接エンコードされるためです。レジスタを間接的にアドレス指定する方法はありません。
(2) のレジスタ数を制限する主な要因は次のとおりです。
(1) の潜在的な回避策は、ループ展開です。ループが配列へのインデックスとしてループ カウンターを使用する場合、ループを展開すると (#pragma unroll
または手動で)、配列アクセスごとに個別の SASS 命令が存在するため、配列インデックスが定数になります。
この NVIDIA プレゼンテーションに部分的に基づいています: Local Memory and Register Spilling。このドキュメントでは、変数と配列の場所がパフォーマンスに与える影響についても詳しく説明しています。
定義したカーネル内のローカル配列は、十分なレジスタがない場合、レジスタとローカル メモリに割り当てられます。
配列を共有メモリに割り当てる場合は、次のように指定する必要があります。
__shared__ int my_array[100];