2

CUDAのデバイスに背景画像データを保存したい。後でビデオソースから新しいシーンを読み取っているときに、新しいシーンを前景画像としてGPUに送信し、背景画像から差し引きたいと思います。シーンごとに背景画像をGPUに再送したくありません。これどうやってするの?

4

2 に答える 2

3

バックグラウンド イメージをデバイス メモリ配列 (GPU 上) に保存します。次に、フォアグラウンド イメージを読み取るときに、cudaMemcpyそれを別のデバイス メモリ アレイにコピーします。次に、2 つのデバイス メモリ アレイを引数として取り、イメージ減算を実行するカーネルを起動します。シンプルであるべきです。

デフォルトのコンテキスト作成を使用し、これがすべて同じ CPU スレッドで実行されていると仮定すると、Bart がコメントしたように、CUDA コンテキストを「そのまま」維持するために何か特別なことをすることを心配する必要はありません。ただし、CPU マルチスレッドを行う場合は、コンテキスト管理を行う必要があります。

于 2012-04-22T23:16:27.483 に答える
1

ここに簡単な例があります..

int main(int argc, char **argv) {
    uint *hostBackground, *hostForeground; //new uint[]..
    uint *background, *foreground;

まず、バックグラウンド データとフォアグラウンド データを初期化します。

    cudaMalloc(background, ..);
    cudaMalloc(foreground, ..);

次に、バックグラウンド データを読み込みます

    cudaMemCpy(background, hostBackground, ..); //copy to device..

次に、前景データを読み取ります

    while (applicationRuns) {
        readImage(hostForeground); //read image..
        cudaMemcpy(foreground, hostForeground, ..); //copy to device

        //operate on foreground..
        substruct_kernel<<<threads, blocks>>>(foreground, background, width, height);

        cudaMemcpy(hostForeground, foreground, ..); //copy to host

        //use hostForeground
    }

それらを解放する

    cudaFree(foreground);
    cudaFree(background);
}

これは単純な substruct カーネルです。

__global__ void substruct_kernel(uint *foreground, uint *backgroung, int width, int height)
{
    int idx = threadIdx.x + threadDim.x * blockIdx.x;
    int idy = threadIdx.y + threadDim.y * blockIdx.y;

    if (idx < width && idy < height)
       foreground[idx + idy * width] -= background[idx + idy * width]; //clamp may be required..
}

このような単純な操作にはライブラリを使用することをお勧めします。Blas ライブラリまたは Thrust ライブラリがオプションになる場合があります。

于 2012-08-22T13:52:33.197 に答える