1

CUDAに問題があります。charの配列から文字を数える小さなプログラムを作りたいです。

ファイルから文字を読み取り、読み取った文字の数であるNというint変数に保存します。その後、私はmallocします。

char *b_h, *b_d;
size_t size_char = N * sizeof(char);
b_h = (char *)malloc(size_char);

mallocの後、ファイルを再度読み取り、現在の文字をchar配列の要素に割り当てます(機能します)。

int j=0;
while(fscanf(file,"%c",&l)!=EOF)
{
    b_h[j]=l;
    j++;
}

その後、カウンターとしてint変数(a_h)を作成します。

int *a_h, *a_d;
size_t size_count = 1*sizeof(int);
a_h = (int *)malloc(size_count);

わかりました、CUDAを使用してください:

cudaMalloc((void **) &a_d, size_count);
cudaMalloc((void **) &b_d, size_char);

ホストからデバイスにコピーします。

cudaMemcpy(a_d, a_h, size_count, cudaMemcpyHostToDevice);
cudaMemcpy(b_d, b_h, size_char, cudaMemcpyHostToDevice);

ブロックを設定し、CUDA関数を呼び出します。

int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
square_array <<< n_blocks, block_size >>> (a_d,b_d,c_d, N);

関数から受信:

cudaMemcpy(a_h, a_d, size_count, cudaMemcpyDeviceToHost);
cudaMemcpy(b_h, d_d, size_char, cudaMemcpyDeviceToHost);

そして印刷数:

printf("\Count: %d\n", a_h[0]);

そして、それは機能しません。charの配列に次の文があります:Super testSuper test; 'e'の文字を探していて、a_h [0] = 1になりました。どこに問題がありますか?

CUDA機能:

__global__ void square_array(int *a, char *b, int *c, int N)
{
const char* letter = "e";

int idx = blockIdx.x * blockDim.x + threadIdx.x;

if (idx<N) 
{
    if(b[idx] == *letter)
    {
        a[0]++;
    }
}
}

私を助けてください。

4

1 に答える 1

2

N は、GPU がすべてのスレッドを並行して起動できるほど十分に小さいと推測しています。したがって、配列内の文字ごとにスレッドを開始します。すべて同時に実行されているスレッドは、相互の出力を認識しません。代わりに、各スレッドは a[0] の値 (0) を読み取り、それを 1 増やして、結果の値 (1) を格納します。もしこれが宿題なら、それが教授が伝えたかった基本的なレッスンだったでしょう。

複数のスレッドが同時に同じ場所に値を保存する場合、どのスレッドがその値を保存するかは未定義です。あなたの場合、値を格納するすべてのスレッドが値「1」を格納するため、それは問題ではありません。

一般的な解決策は、各スレッドに 0 または 1 の値を (一致するかどうかに応じて) 別の場所に保存させ、別のステップで値を合計することです。

アトミック増加操作を使用することもできます。

于 2012-04-15T03:14:09.903 に答える