cudaMemcpy セグメンテーション フォールト: 洞察とトラブルシューティング
「cudaMemcpy セグメンテーション フォールト」エラーは、cudaMemcpy が無効なメモリ アドレスで動作するときによく発生します。この問題を詳しく調べるために、投稿された問い合わせの特定の例に焦点を当ててみましょう:
cudaMemcpy(CurrentGrid->cdata[i], Grid_dev->cdata[i], size*sizeof(float),\ cudaMemcpyDeviceToHost);
コードとデバッグ情報を調査した結果、ポインター Grid_dev->cdata[i] が NULL であることが判明しました。デバイス上で、cudaMemcpy で逆参照されるときにセグメンテーション違反が発生しました。 call.
デバイス ポインターの逆参照が失敗する理由
デバイス ポインターは cudaMemcpy 呼び出しで使用できますが、ポインターにはデバイス アドレスのみが格納されることを覚えておくことが重要です。デバイス上の実際のデータにアクセスするには、追加の cudaMemcpy を実行して、ポインタ値をデバイスからホスト ポインタにコピーする必要があります。このホスト ポインタは、データへのアクセスに使用できます。
この問題に対処するためにコードが改訂されました
元のコードは、より適切なアプローチで修正されました。
float * A; cudaMalloc((void**)&A, sizeof(float)); ... ... cudaMemcpy(&A, &(Grid_dev->cdata[i]), sizeof(float *), cudaMemcpyDeviceToHost); CurrentGrid->cdata[i] = new float[size]; cudaMemcpy(CurrentGrid->cdata[i], A, size*sizeof(float), cudaMemcpyDeviceToHost);
ここでは、浮動小数点ポインター A をデバイスに割り当て、cudaMemcpy の値をGrid_dev->cdata[i] を A に送信します。次に、A をホストに cudaMemcpy します。これにより、ポインタ値を直接間接参照するのではなく、確実にキャプチャすることができます。
潜在的なメモリ リーク
ポインタ A が次の場合、変更されたコードはメモリ リークを引き起こす可能性があります。データのコピー操作後に解放されません。これを軽減するには、A に割り当てられたメモリを cudaFree(A) を使用して解放する必要があります。
以上がcudaMemcpy が NULL デバイス ポインタを逆参照するとセグメンテーション フォールトを引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。