0

CUDA プログラムを作成していますが、問題が発生しています。私には2つの機能があります:

  1. __global__ void cal_freq_pl(float *, char *, char *, int *, int *)
  2. __global__ void cal_sum_vfreq_pl(float *, float *, char *, char *, int *)

最初の関数を次のように呼び出します cal_freq_pl<<<M,512>>>( ... ); 。M は約 15 の数値なので、気にする必要はありません。512 は、GPU のブロックあたりの最大スレッド数です。これは正常に機能し、すべての M*512 値に対して期待される出力が得られます。

しかし、同様の方法で 2 番目の関数を呼び出すと、機能し cal_sum_vfreq_pl<<<M,512>>>( ... ); ません。その関数のがらくたをデバッグした後、最終的に次の次元で実行されることがわかりました: cal_sum_vfreq_pl<<<M,384>>>( ... );、これは 512 よりも 128 小さいです。512 ではエラーは表示されませんが、誤った結果が表示されます。

現在、Compute1.0 arch にしかアクセスできず、Windows 64 ビット マシンで Nvidia Quadro FX4600 グラフィック カードを使用しています。

このような動作が発生する理由はわかりませんが、最初の関数は 512 スレッドで実行され、2 番目の関数は 384 (またはそれ以下) でのみ実行されると確信しています。

誰かが可能な解決策を提案してもらえますか?

前もって感謝します...

編集:カーネルコードは次のとおりです。

__global__ void cal_sum_vfreq_pl(float *freq, float *v_freq_vectors, char *wstrings, char *vstrings, int *k){
    int index = threadIdx.x;
    int m = blockIdx.x;
    int block_dim = blockDim.x;
    int kv = *k; int vv = kv-1; int wv = kv-2;
    int woffset = index*wv;
    int no_vstrings = pow_pl(4, vv);
    float temppp=0;
    char wI[20], Iw[20]; int Iwi, wIi;
    for(int i=0;i<wv;i++) Iw[i+1] = wI[i] = wstrings[woffset + i];
    for(int l=0;l<4;l++){
            Iw[0] = get_nucleotide_pl(l);
            wI[vv-1] = get_nucleotide_pl(l);
            Iwi = binary_search_pl(vstrings, Iw, vv);
            wIi = binary_search_pl(vstrings, wI, vv);
            temppp = temppp + v_freq_vectors[m*no_vstrings + Iwi] + v_freq_vectors[m*no_vstrings + wIi];
    }
    freq[index + m*block_dim] = 0.5*temppp;
}
4

1 に答える 1

1

2 番目のカーネルで多くのレジスタを割り当てたようです。ブロックあたりのレジスタ数などのハードウェア リソースの制限により、ブロックあたりの最大スレッド数に常に到達できるとは限りません。

CUDA は、ブロックごとの適切なスレッド数を計算するのに役立つツールを提供します。

http://developer.download.nvidia.com/compute/cuda/CUDA_Occupancy_calculator.xls

この .xls ファイルは、CUDA インストール ディレクトリにもあります。

于 2013-02-05T11:22:35.580 に答える