GPUコンピューティングがシミュレーションの高速化にどの程度役立つのか疑問に思っています。
私のコードの重要な部分は行列の乗算です。基本的に、コードは次のようになりますpython 1000次の行列と長いforループを持つコード。
import numpy as np
m_size = 1000
sim_length = 50
a = np.random.Rand(m_size, m_size)
b = np.random.Rand(m_size, m_size)
for j in range(sim_length):
result = np.dot(a,b)
注:私の行列は密集していて、ほとんどがランダムで、forループはcythonでコンパイルされています。
私の素朴な推測は、私には2つの要因があるということです。
この視点は素朴なものだと思いますが、何が欠けているのでしょうか。
numpy
を使用する場合は、ATLAS、OpenBLAS、MKLなどのBLASライブラリの1つを計算バックエンドとして使用している可能性があります。最速のMKLを使用している場合は、ここで最近のパフォーマンスベンチマークを見つけることができます。 、最近のNvidia GPUK40mとIntelXeon12コアE5-2697v2 @ 2.70GHzの間
https://developer.nvidia.com/cublas
ここで、K40mは12スレッドのE5-2697よりも6倍高速です。 MKLを考慮すると、マルチコアCPUで適切に拡張できます。 K40mは、1スレッドのE5-2697よりも約72倍高速です。また、1000-dimは、GPUとCPUの両方を完全に利用するためのほぼ下限であることに注意してください。通常、マトリックスサイズが小さいほど、GPUのパフォーマンスが低下します。
numpy
に低速のBLASバックエンドを使用している場合は、GNUライセンスのATLASと言います。次に、MKLとATLASの比較をここで見つけることができます
https://software.intel.com/en-us/intel-mkl/benchmarks#DGEMM-ATLAS
ここで、MKLはATLASより2〜4倍高速です。
Nvidia GPUの場合、広く使用されているバックエンドはCUDAのcuBLASのみであるため、パフォーマンスはATLASとMKLのように大きく変わることはありません。
@janbrohlが言うように、ホストRAMとGPUデバイスメモリ間のデータ転送は、全体的なパフォーマンスに影響を与える重要な要素です。これがデータ転送速度のベンチマークです。
行列のサイズが与えられると、実際には、計算とデータ転送のそれぞれの絶対時間を計算できます。これらは、パフォーマンスをより適切に評価するのに役立ちます。
GPUでのパフォーマンスを最大化するには、行列の乗算だけでなく、すべての計算操作をGPUに移動することにより、データ転送を最小化するようにプログラムを再設計する必要があります。
一般的に言えば、GPUは、大きな行列の乗算などの高度に並列化された単純なタスク(つまり、GPUの目的)ではCPUよりもはるかに高速ですが、GPUの計算にはいくつかの問題があります。
したがって、乗算自体は100倍(またはそれ以上)速くなる可能性がありますが、実際にははるかに小さいスピードアップまたはスローダウンが発生する可能性があります
分岐コードの大幅な速度低下、手作業によるキャッシュの処理など、GPUの高速プログラムの作成を非常に困難にする可能性があるCPUと比較して、GPUが「愚か」であるという問題が多くあります。
Opencl apiを使用して、1280コアのHD7870(主流のデスクトップグレードのGPUでさえも)で8k X 8k x 8k X 8kの乗算を試しましたが、約0.99秒かかり、約5,400億の追加と5,400億の乗算、つまり1.1Tflopsを意味します。 (そのピーク値の%40はその広告で述べられています)。ハイエンドのデスクトップグレードのCPUは、統合されたGPUを除いて、0.2〜0.3 Tflops(ピーク値)しかありません。したがって、最高のCPUは、パフォーマンスとワットあたりのパフォーマンス、およびドルあたりのパフォーマンスの両方で中低レベルのGPUに到達することさえできません。
パフォーマンスの主なオプション:
ハードウェアの違いを最適化する
1から4までのオプションがあるライブラリを使用する