0

GPU でいくつかの画像処理操作を実行しており、出力のヒストグラムが必要です。処理カーネルを作成してテストしました。また、出力画像のサンプルのヒストグラム カーネルを個別にテストしました。どちらも正常に動作しますが、すべてを 1 つのループに入れると何も得られません。

これは私のヒストグラムカーネルです:

__global__ void histogram(int n, uchar* color, uchar* mask, int* bucket, int ch, int W, int bin)
{
    unsigned int X = blockIdx.x*blockDim.x+threadIdx.x;
    unsigned int Y = blockIdx.y*blockDim.y+threadIdx.y;

    int l = (256%bin==0)?256/bin: 256/bin+1;
    int c;

    if (X+Y*W < n && mask[X+Y*W])
    {
        c = color[(X+Y*W)*3]/bin;
        atomicAdd(&bucket[c], 1);

        c = color[(X+Y*W)*3+1]/bin;
        atomicAdd(&bucket[c+l], 1);

        c = color[(X+Y*W)*3+2]/bin;
        atomicAdd(&bucket[c+l*2], 1);
    }
}

赤、緑、青のヒストグラム ベクトルを更新しています ('l' はベクトルの長さです)。atomicAdds をコメント アウトすると、再び出力が生成されますが、もちろんヒストグラムは生成されません。なぜ彼らは一緒に働きませんか?

編集:

これはループです:

    cudaMemcpy(frame_in_gpu,frame_in.data, W*H*3*sizeof(uchar),cudaMemcpyHostToDevice);
    cuda_process(frame_in_gpu, frame_out_gpu, W, H, dimGrid,dimBlock);
    cuda_histogram(W*H, frame_in_gpu, mask_gpu, hist, 3, W, bin, dimg_histogram, dimb_histogram);

次に、出力をホスト メモリにコピーし、ビデオに書き込みます。これらは、入力として与えられた dimGrid と dimBlock でのみカーネルを呼び出す c コードです。また:

dim3 dimBlock(32,32);
dim3 dimGrid(W/32,H/32);
dim3 dimb_Histogram(16,16);
dim3 dimg_Histogram(W/16,H/16);

これをヒストグラムに変更したのは、それでうまくいったからです。それは問題ですか?

Edit2: コンパイルに -arch=sm_11 オプションを使用しています。どこかで読んだだけです。どうやって選べばいいのか誰か教えてください。

4

1 に答える 1

1

おそらく、-arch=sm_11フラグなしでコンパイルを試みる必要があります。sm 1.1は、GPUがSM 2.0をサポートしている間に、グローバルメモリでのアトミック操作をサポートした最初のアーキテクチャです。したがって、下位互換性がない限り、SM1.1用にコンパイルする理由はありません。

考えられる問題の1つは、SM1.1がグローバルメモリ内の64ビットintでのアトミック操作をサポートしていないことです。したがって、-archオプションを指定せずにコードを再コンパイルするか、必要に応じて-arch=sm_20を使用することをお勧めします。

于 2012-07-29T23:46:37.987 に答える