0

float の配列を更新する CUDA コードをいくつか実行しました。「 CUDA コードをコンパイルして C++ プロジェクトにリンクするにはどうすればよいですか?」で説明されているようなラッパー関数があります。この質問。

CUDA 関数内で、このような for ループを作成します...

int tid = threadIdx.x;
for(int i=0;i<X;i++)
{
     //code here
}

ここでの問題は、X が 100 の値に等しい場合、すべて正常に動作しますが、X が 1000000 に等しい場合、ベクトルが更新されないことです (for ループ内のコードが実行されないかのように)。

ラッパー関数内で、for ループで CUDA 関数を呼び出しても、問題なく動作します (ただし、CPU で同じプロセスをすべて実行した場合よりも何らかの理由で大幅に遅くなります)。このように...

for(int i=0;i<1000000;i++)
{
      update<<<NumObjects,1>>>(dev_a, NumObjects);
}

ラッパー関数で100万回ループできるのに、単にCUDAの「更新」関数を1回呼び出してから、その関数内で100万回のforループを開始できない理由を知っている人はいますか?

4

1 に答える 1

0

これを実行した後、cudaThreadSynchronize と cudaGetLastError を使用して、エラーが発生したかどうかを確認する必要があります。初めて、タイムアウトしたと思います。これは、カーネルが完了するまでに長い時間がかかる場合に発生します。カードはそれをあきらめるだけです。

2 つ目の理由は、実行に時間がかかる理由です。これは、カーネルの起動ごとにオーバーヘッド時間が設定されているためです。カーネル内にループがあると、このオーバーヘッドが一度発生し、ループが実行されます。今、あなたはそれをX回経験しています。オーバーヘッドはかなり小さいですが、できるだけ多くのループをカーネル内に配置するのに十分な大きさです。

X が特に大きい場合は、安全な時間内に完了するまでカーネル内で可能な限り多くのループを実行してから、これらのカーネルをループします。

于 2012-03-26T06:01:59.760 に答える