0

小さな入力データ (= 512 要素) の非常にダンプされた並べ替えアルゴリズムをプロファイリングしています。合体した構造体の配列を読み取るカーネルを呼び出しています。

構造体は次のようになります。

struct __align__(8) Elements 
{
     float weight;
     int value;
};

nvprof は、L1 ミス/ヒットおよび gdl 命令について次の命令カウントを提供します。

                  Invocations    Avg       Min       Max  Event Name
        Kernel: sort(Elements*)
                      500         0         0         0  gld_inst_8bit
                      500         0         0         0  gld_inst_16bit
                      500      1024      1024      1024  gld_inst_32bit
                      500         0         0         0  gld_inst_64bit
                      500         0         0         0  gld_inst_128bit
                      500       120       120       120  l1_global_load_hit
                      500       120       120       120  l1_global_load_miss
                      500         0         0         0  uncached_global_load_tr.

次のように構造体のレイアウトを変更すると:

struct __align__(8) Elements 
{
     float weight;
     float value;
};

プロファイリングの出力は次のようになります。

                  Invocations    Avg       Min       Max  Event Name
Device 0
        Kernel: sort(Elements*)
                      500         0         0         0  gld_inst_8bit
                      500         0         0         0  gld_inst_16bit
                      500         0         0         0  gld_inst_32bit
                      500       512       512       512  gld_inst_64bit
                      500         0         0         0  gld_inst_128bit
                      500         0         0         0  l1_global_load_hit
                      500       120       120       120  l1_global_load_miss
                      500         0         0         0  uncached_global_load_tr.

実行時間への影響はまったくありませんが、GPU がコードの最初のバリアントで 32 ビットのロード命令を実行し、2 番目のバリアントで 64 ビットの命令を実行する理由がわかりません。

カーネルは 1 ブロックと 512 スレッドで呼び出されます (そのため、l1_global_load_x カウンターが正しくない可能性があります)。すべてが CUDA 5.0 を搭載した GeForce 480 で行われます。

EDIT: ソートカーネル(少し短縮):

__global__ void sort(Elements* nearest)
{
    ThreadIndex idx = index();

    __shared__ Elements temp[MAX_ELEMENTS];
    __shared__ int index_cache[MAX_ELEMENTS];

    temp[idx.x] = nearest[idx.x];

    WeightedElements elem = temp[idx.x];
    __syncthreads();

    int c = 0;

    // some index crunching 

    nearest[idx.x] = temp[c];
}
4

1 に答える 1