3

私は最近CUDAを学び始めました、そして私は理解できない非常に奇妙な行動に出くわしました。

私のコードは基本的に、単純なatomicAddカーネルの平均実行時間を計算します。これを実現するために、カーネルをループで呼び出して、より良い平均を取得します。実行時間の見積もりにこれを含めたいので、デバイスのメモリ割り当てとコピーをループに含めます。問題は、ループを通過する実行回数が多すぎると、プログラムがランタイムAPIエラー30で失敗することがよくあることです。

メモリアクセスに問題があるのではないかと思ったので、プログラムでmemcheckを実行しても無駄になりました。明らかにメモリエラーはありません。また、カーネルを数回実行するだけであれば問題はありません。これは、カーネルが正確に問題ではないことを示しているようにも見えます。問題が発生するのは、頻繁に連続して呼び出す場合のみです。

私のコードのスケルトンは次のとおりです。

for(int i = 0; i < runs; i++)
{


    //////////////////////////////////
    // Copy memory from Host to Device
    //////////////////////////////////

    cutilSafeCallNoSync( cudaMemcpy(dev_waveforms, waveforms, num_wf * wf_length *  sizeof(float), 
                        cudaMemcpyHostToDevice) );
    cutilSafeCallNoSync( cudaMemcpy(dev_delays, delays, num_wf * sizeof(int), 
                        cudaMemcpyHostToDevice) );




    ////////////////////////
    // Kernel Call
    ////////////////////////

    kernel_wrapper<float>(dev_waveforms, dev_focused, dev_delays, 
                    wf_length, num_wf, threads, blocks, kernel); 

    //copy back to host memory.
    cutilSafeCallNoSync( cudaMemcpy(focused, dev_focused, J * wf_length * sizeof(float), 
        cudaMemcpyDeviceToHost) );

}

繰り返しますが、これは実行が十分に大きい場合にのみ失敗します。他にも奇妙なことが起こっていますが、とりあえずこれのままにしておきます。

ああ、私はVisual Studio2010を使用してWindows7で開発しています。私のGPUはビデオカードとしても機能しており、これが奇妙な影響を与えるのではないかと心配しています。

前もって感謝します!

4

3 に答える 3

2

Windows 7ドライバーは、WDDMのドライバーオーバーヘッドの増加を回避するために、複数のコマンドを1つの送信にまとめることができます(Win XPなどのWDDM以前のドライバーと比較して)。このため、単一のカーネルがウォッチドッグを超えていなくても、このようなループで実行される可能性があります。cudaDeviceSynchronize()@RogerDahlがそれを回避しようと提案しているように呼び出すことができます(おそらくN回の反復ごとにのみ)。

または、Linuxで実行します。

編集: ランタイムエラー30は不明なエラーです。これがウォッチドッグタイマーのタイムアウトである場合、cudaErrorLaunchTimeout(エラー6)が予想されます。完全なコードを提供しなかったため、エラーの原因を特定するのは困難です。カーネルコードにバグがあると思います。

于 2012-08-31T04:45:35.527 に答える
1

同じエラーが発生し、割り当てたメモリをカーネルが実際にオーバーランしていることに気付きました。バッファを 2 倍にして問題が解決したので、同じ問題が発生している可能性があります。

私の問題は、起動するスレッドとブロックの数を決定するための数学のバグでした。意図したよりも 8 倍多くのブロックを起動していました。私のカーネル内では、特定のスレッドがどの要素を処理する必要があるかを決定する計算により、配列の外側にアクセスすることになりました。

配列の外部のメモリにアクセス/変更するスレッドの実行を防ぐために、各スレッドが使用している配列の要素を確認してください。

于 2013-01-15T16:53:59.340 に答える
1

エラー 30 メッセージが表示される理由に対する回答を探して、この投稿に来る他の人のために:

GPUデバイス関数の引数の 1 つとして誤って CPU 変数を指定した場合にも、このエラーが発生します。これは、私にとってこの問題の最も一般的な原因です。変数の cpu コピーを誤って引数として配置することを何度も繰り返した後、学習するだろうと思うでしょうが、...

デバイス関数のすべての引数を確認してください: myDeviceFunciont<<<1,N>>>(argument1, argument2, argument3)

GPU変数です(つまり、cudaMallocおよびcudaMemcpyでGPUにメモリを割り当てるために使用した変数)

于 2013-04-12T15:56:39.030 に答える