メイン プログラムに大きな char 配列があり、それをチャンクでデバイス メモリにコピーします。プログラムで約 500,000 のスレッドを実行し、各スレッドは 2000 文字にアクセスします。したがって、コードを使用して一度に 500,000 * 2000 = 1GB バイトを転送します
err = cudaMemcpy (dev_database, adjusted_database[k], JOBS * 2000 * sizeof(char), cudaMemcpyHostToDevice);
if(err != cudaSuccess) { printf("CUDA error: %s\n", cudaGetErrorString(err)); exit(EXIT_FAILURE); }
私のカーネルでは、3 つの共有配列も定義しています
//__shared__ char dev_query[200];
__shared__ float dev_scores[200*5];
__shared__ int dev_index[26];
そしてそれらを初期化します
if(threadIdx.x == 0) {
//for(i = 0; i < 200; i++){ dev_query[i] = dev_query_constant[i]; }
for(i = 0; i < 200 * 5; i++){ dev_scores[i] = dev_scores_constant[i]; }
for(i = 0; i < 26; i++){ dev_index[i] = dev_index_constant[i]; }
}
__syncthreads();
コメントされた 2 行でプログラムを実行すると、カーネルが奇妙な値を返し、char 配列の 2 番目のチャンクをコピーするとエラーが発生します。
CUDA エラー: 不明な起動エラー
上記のコードの行のコメントを外すと、すべて正常に動作します。1GB ではなく 100MB など、配列の小さなチャンクをコピーすると、上記と同じエラーが発生する 6 番目のチャンクに到達するまで正常に動作します。
これは非常に奇妙な動作であり、なぜこれが起こっているのかを理解したいと思います。これを引き起こしているバグはどこかにありますか?小さなチャンク (100MB など) を転送し、他のチャンクを無視すると、プログラムは正常に動作するため、特定するのは困難です。共有変数に関連する行のコメントを外したり、共有変数を定数に変更したりしても、問題なく動作します。どんな助けでも大歓迎です。ありがとう!
編集: これが私のカーネルです。要約すると、2 つの文字列の類似性スコアを、0 からそれらの長さまでのすべての i の i 番目の文字を比較することによって計算しています。以下のコードは、 の直後の行のコメントを解除しない限り、上記のエラーを生成します if(threadIdx.x == 0) {
。または、以下の共有配列を定数配列に置き換えると、正常に動作します。
__global__ void assign7(int jobs_todo, char* database, float* results, int flag) {
unsigned int id = threadIdx.x + blockIdx.x * blockDim.x;
if(id < jobs_todo) {
__shared__ char dev_query[200];
__shared__ float dev_pos_specific_scores[200*5];
__shared__ int dev_subst_index[26];
int j_, i, p, stop, k; //stop2;
float score=0, max=0;
char ch; //ch1, ch2;
if(threadIdx.x == 0) {
//for(i = 0; i < 51; i++){ dev_query[i] = dev_query_constant[i]; }
for(i = 0; i < 5 * 200; i++){ dev_pos_specific_scores[i] = dev_pos_specific_scores_constant[i]; }
for(i = 0; i < 26; i++){ dev_subst_index[i] = dev_subst_index_constant[i]; }
}
__syncthreads();
for(i = 1; i <= 2000 - 51; i += 1){
p = jobs_todo*(i-1);
score = 0;
stop = 51/1; stop = stop*1;
for(j_ = 1; j_ <= stop; j_ += 1){
k = (j_-1)*5;
ch = database[p + id];
score += dev_pos_specific_scores[k + dev_subst_index[ch - 'A']];
if(score < 0) score = 0;
if(score > max) max = score;
p += jobs_todo;
}
}
results[id] = max;
}
}