2

cudaMalloc を使用してデバイスにメモリを割り当て、それをカーネル関数に渡しました。カーネルが実行を終了する前にホストからそのメモリにアクセスすることは可能ですか?

4

4 に答える 4

3

カーネルがまだ実行されている間にmemcpyを開始させるために私が考えることができる唯一の方法は、カーネルとは異なるストリームで非同期memcpyを送信することです。(カーネル起動または非同期memcpyのいずれかにデフォルトのAPIを使用する場合、NULLストリームは2つの操作を強制的にシリアル化します。)

ただし、カーネルの実行をストリームと同期させる方法がないため、そのコードは競合状態の影響を受けます。つまり、コピーエンジンは、カーネルによってまだ書き込まれていないメモリからプルする可能性があります。

マップされたピン留めされたメモリをほのめかした人は何かに夢中です。カーネルがマップされたピン留めされたメモリに書き込む場合、データの処理が完了すると、データをホストメモリに効果的に「コピー」します。このイディオムは、カーネルがデータに再度アクセスしない限り、うまく機能します。

于 2012-06-14T14:42:21.270 に答える
1

可能ですが、カーネルの進行状況がわからないため、このような方法で取得したメモリの内容については保証されません。

あなたが達成しようとしているのは、データ転送と実行をオーバーラップさせることです。これは、ストリームを使用することで可能になります。複数のCUDAストリームを作成し、各ストリームでカーネル実行とデバイスからホストへのcudaMemcpyをキューに入れます。たとえば、場所「0」を埋めるカーネルとその場所からホストに戻るcudaMemcpyをストリーム0に戻し、場所「1」を埋めるカーネルと「1」からcudaMemcpyをストリーム1に戻します。 GPUが「0」からのコピーと「1」の実行をオーバーラップすること。CUDAのドキュメントを確認してください。どこかにドキュメント化されています(ベストプラクティスガイドにあると思います)。

于 2012-06-13T23:09:10.513 に答える
0

カーネルが実行されているかどうかに関係なく、ホストから GPU メモリに直接アクセスすることはできません。

カーネルがメモリへの書き込みを完了する前にそのメモリをホストにコピーすることについて話している場合、答えはデバイスの計算能力によって異なります。ただし、最も古いチップを除くすべてのチップは、カーネルの実行中にデータ転送を実行できます。

ただし、カーネルによってまだ更新されているメモリをコピーする必要はないようです。部分的に完成したデータのランダムなスナップショットを取得します。代わりに、デバイスに 2 つのバッファーがあるものをセットアップしたい場合があります。GPU が別のバッファーで作業している間に、バッファーの 1 つをコピーできます。

アップデート:

あなたの説明に基づいて、あなたが得ることができる最も近いのは、ゼロコピーメモリとも呼ばれる、マップされたページロックされたホストメモリを使用することだと思います。このアプローチでは、値はカーネルによって書き込まれるときにホストにコピーされます。カーネルにクエリを実行して実行した作業の量を確認する方法はないため、メモリを繰り返しスキャンして新しく書き込まれた値を探す必要があると思います。詳細については、CUDA プログラミング ガイド v4.2 のセクション 3.2.4.3、Mapped Memory を参照してください。

私はこれをお勧めしません。非常に特殊な要件がない限り、タスクを達成するためのより良い方法がある可能性があります。

于 2012-06-12T23:40:58.070 に答える
0

カーネルを起動すると、非同期 (非ブロッキング) 呼び出しになります。cudaMemcpy next を呼び出すと、カーネルが終了するまでブロックされます。

デバッグ目的で結果を取得したい場合は、カーネルをステップスルーしてメモリを検査できる cudaDebugging を使用することが可能かもしれません。

小さな結果チェックの場合、カーネル コードで printf() を使用することもできます。

または、その特定の結果に関心がある場合は、サイズ (1,1) のスレッドブロックのみを実行します。

于 2012-06-13T23:00:40.043 に答える