9

CUDA 4.x で への最初の呼び出しが途方もなくcudaMalloc 遅くなることは秘密ではありません (これは何度か報告されています)、一見 CUDA ドライバーのバグのようです。

最近、奇妙な動作に気付きました: の実行時間はcudaMalloc 、プログラムにリンクしたサードパーティの CUDA ライブラリの数に直接依存します (これらのライブラリは使用しないことに注意してください。プログラムをリンクするだけです)。

次のプログラムを使用していくつかのテストを実行しました。

int main() {
  cudaSetDevice(0);
  unsigned int *ptr = 0;
  cudaMalloc((void **)&ptr, 2000000 * sizeof(unsigned int));   
  cudaFree(ptr);
return 1;
}

結果は次のとおりです。

  • リンク先: -lcudart -lnpp -lcufft -lcublas -lcusparse -lcurand 実行時間: 5.852449

  • リンク先: -lcudart -lnpp -lcufft -lcublas 実行時間: 1.425120

  • リンク先: -lcudart -lnpp -lcufft 実行時間: 0.905424

  • リンク先: -lcudart 実行時間: 0.394558

「gdb」によると、時間は実際に私のcudaMallocに入るので、ライブラリの初期化ルーチンが原因ではありません..

誰かがこれについてもっともらしい説明を持っているのだろうか?

4

1 に答える 1

11

あなたの例では、cudaMalloc呼び出しは GPU で遅延コンテキストの確立を開始します。ランタイム API ライブラリが含まれている場合、そのバイナリ ペイロードを検査し、そこに含まれる GPU elf シンボルとオブジェクトをコンテキストにマージする必要があります。ライブラリが多いほど、プロセスにかかる時間が長くなることが予想されます。さらに、cubin のいずれかにアーキテクチャの不一致があり、下位互換性のある GPU を使用している場合、ターゲット GPU のデバイス コードのドライバー再コンパイルをトリガーすることもできます。非常に極端な例として、古いバージョンの CUBLAS にリンクされた古いアプリケーションを Fermi GPU で実行すると、読み込みと初期化に数十秒かかることがわかりました。

cudaFree次のような呼び出しを発行することで、遅延コンテキストの確立を明示的に強制できます。

int main() {
    cudaSetDevice(0);
    cudaFree(0); // context establishment happens here
    unsigned int *ptr = 0;
    cudaMalloc((void **)&ptr, 2000000 * sizeof(unsigned int));   
    cudaFree(ptr);
  return 1;
}

タイマーを使用してこのバージョンをプロファイリングまたは計測すると、最初のcudaFree呼び出しでほとんどのランタイムが消費され、cudaMalloc呼び出しがほとんど無料になることがわかります。

于 2012-07-26T08:46:26.907 に答える