6

次の出力を見て、数字に頭を悩ませようとしています。

==2906== Profiling result:
Time(%)      Time     Calls       Avg       Min       Max  Name
 23.04%  10.9573s     16436  666.67us  64.996us  1.5927ms  sgemm_sm35_ldg_tn_32x16x64x8x16
 22.28%  10.5968s     14088  752.18us  612.13us  1.6235ms  sgemm_sm_heavy_nt_ldg
 18.09%  8.60573s     14088  610.86us  513.05us  1.2504ms  sgemm_sm35_ldg_nn_128x8x128x16x16
 16.48%  7.84050s     68092  115.15us  1.8240us  503.00us  void axpy_kernel_val<float, int=0>(cublasAxpyParamsVal<float>)
...
  0.25%  117.53ms      4744  24.773us     896ns  11.803ms  [CUDA memcpy HtoD]
  0.23%  107.32ms     37582  2.8550us  1.8880us  8.9556ms  [CUDA memcpy DtoH]

...

==2906== API calls:
Time(%)      Time     Calls       Avg       Min       Max  Name
 83.47%  41.8256s     42326  988.18us  16.923us  13.332ms  cudaMemcpy
  9.27%  4.64747s    326372  14.239us  10.846us  11.601ms  cudaLaunch
  1.49%  745.12ms   1502720     495ns     379ns  1.7092ms  cudaSetupArgument
  1.37%  688.09ms      4702  146.34us     879ns  615.09ms  cudaFree
...

メモリ アクセスの最適化に関して、さまざまな実装を比較するときに実際に確認する必要がある数値は何ですか? 最初は(両方向に)memcpy取るだけのように見えますが、さらに多くの API 呼び出し:があります。また、最小/平均/最大列は、上位出力ブロックと下位出力ブロックの間で加算されません。117.53+107.32mscudaMemcpy41.8256s

なぜ違いがあり、メモリ転送を最適化するために重要な「真の」数は何ですか?

EDIT : 2 番目の質問は、たとえば、誰がaxpy_kernel_val(そして何回) 呼び出しているかを把握する方法はありますか?

4

1 に答える 1

5

合計時間の違いは、作業が GPU に対して非同期的に開始されるという事実によるものです。ホストへの明示的な同期を持たない長時間実行されているカーネルまたはカーネルのセットがあり、その後に へcudaMemcpycudaMemcpy呼び出しを行う場合、カーネルが実行を完了するかなり前に呼び出しが開始されます。API 呼び出しの合計時間は、起動された瞬間から完了する瞬間までであるため、実行中のカーネルと重複します。NVIDIA Visual Profiler を介して出力を実行すると、これが非常に明確にわかります ( nvprof -o xxx ./myApp、次に xxx を nvvp にインポートします)。

違いは、起動のオーバーヘッドによる最小時間です。API プロファイリングではすべての起動オーバーヘッドが考慮されますが、カーネルのタイミングにはそのごく一部しか含まれていません。ここでわかるように、起動オーバーヘッドは最大 10 ~ 20us になる可能性があります。

一般に、API 呼び出しセクションでは CPU が何をしているかがわかりますが、プロファイリング結果では GPU が何をしているかがわかります。この場合、おそらく CPU の使用率が低すぎると思います。おそらく のcudaMemcpy起動が早すぎて、CPU サイクルが浪費されているからです。ただし、実際には、これらの予備のサイクルから有用なものを取得することは、多くの場合、困難または不可能です。

于 2015-05-21T11:12:24.760 に答える