2

nvprof を使用して CUDA プログラムでベンチマーク タイミングを取得しようとしていますが、残念ながら、API 呼び出しまたはカーネルをプロファイリングしていないようです。私はそれを正しく行っていることを確認するために簡単な初心者向けの例を探し、次の Nvidia 開発ブログで見つけました。

https://devblogs.nvidia.com/parallelforall/how-optimize-data-transfers-cuda-cc/

コード:

int main()
{
    const unsigned int N = 1048576;
    const unsigned int bytes = N * sizeof(int);
    int *h_a = (int*)malloc(bytes);
    int *d_a;
    cudaMalloc((int**)&d_a, bytes);

    memset(h_a, 0, bytes);
    cudaMemcpy(d_a, h_a, bytes, cudaMemcpyHostToDevice);
    cudaMemcpy(h_a, d_a, bytes, cudaMemcpyDeviceToHost);

    return 0;
}

コマンドライン:

-bash-4.2$ nvcc profile.cu -o profile_test
-bash-4.2$ nvprof ./profile_test

そのため、一語一語、一行一行複製し、同一のコマンドライン引数を実行しました。残念ながら、私の結果は同じでした:

-bash-4.2$ nvprof ./profile_test
==85454== NVPROF is profiling process 85454, command: ./profile_test
==85454== Profiling application: ./profile_test
==85454== Profiling result:
No kernels were profiled.

==85454== API calls:
No API activities were profiled. 

Nvidia ツールキット 7.5 を実行しています

誰かが私が間違っていることを知っているなら、答えを知って感謝します。

-----編集-----

だから私はコードを次のように変更しました

#include<cuda_profiler_api.h>

int main()
{
    cudaProfilerStart();
    const unsigned int N = 1048576;
    const unsigned int bytes = N * sizeof(int);
    int *h_a = (int*)malloc(bytes);
    int *d_a;
    cudaMalloc((int**)&d_a, bytes);

    memset(h_a, 0, bytes);
    cudaMemcpy(d_a, h_a, bytes, cudaMemcpyHostToDevice);
    cudaMemcpy(h_a, d_a, bytes, cudaMemcpyDeviceToHost);

    cudaProfilerStop();
    return 0;
}

残念ながら、それは物事を変えませんでした。

4

2 に答える 2

2

cudaProfilerStop()スレッドを終了する前に (ランタイム API の場合)を呼び出す必要があります。これによりnvprof、必要なすべてのデータを収集できます。

CUDAドキュメントによると:

まだフラッシュされていないプロファイル情報が失われるのを避けるために、プロファイリングされるアプリケーションは、終了する前に、すべての GPU 作業が (CUDA 同期呼び出しを使用して) 完了したことを確認してから、 cudaProfilerStop()またはを呼び出す必要がありcuProfilerStop()ます。そうすることで、対応するコンテキストのバッファリングされたプロファイル情報が強制的にフラッシュされます。

于 2016-05-01T19:07:20.723 に答える