ベンチマーク(PythonとBLASを使用したc ++)および(numpy)

| | | | | | | | | | | | | | | | | | | | | | | | | | |

BLASおよびLAPACK線形代数機能を多用するプログラムを作成したいと思います。パフォーマンスは問題であるため、ベンチマークを行い、私が採用したアプローチが正当であるかどうかを知りたいと思います。

いわば3人の参加者がいて、単純なマトリックスマトリックスを使用してパフォーマンスをテストしたいと考えています。乗算。出場者は次のとおりです。

  1. Numpy、 dotの機能のみを使用します。
  2. Python、共有オブジェクトを介してBLAS機能を呼び出します。
  3. C ++、共有オブジェクトを介してBLAS機能を呼び出します。

シナリオ

さまざまな次元の行列-行列乗算を実装しました i は5から500まで5刻みで実行され、マトリックス m1m2は次のように設定されます。

  m1 = numpy.random.rand(i、i).astype(numpy.float32)m2 = numpy.random.rand(i、i).astype(numpy.float32) 

1。 Numpy

使用されるコードは次のようになります。

  tNumpy = timeit.Timer( "numpy.dot(m1、m2)"、 "import numpy; from __main__ import m1 、m2 ")rNumpy.append((i、tNumpy.repeat(20、1))) 

2。 Python、共有オブジェクトを介してBLASを呼び出す

関数を使用

  _blaslib = ctypes.cdll.LoadLibrary( "libblas.so")def Mul(m1、m2、i 、r):no_trans = c_char( "n")n = c_int(i)one = c_float(1.0)zero = c_float(0.0)_blaslib.sgemm_(byref(no_trans)、byref(no_trans)、byref(n)、byref (n)、byref(n)、byref(one)、m1.ctypes.data_as(ctypes.c_void_p)、byref(n)、m2.ctypes.data_as(ctypes.c_void_p)、byref(n)、byref(zero) 、r.ctypes.data_as(ctypes.c_void_p)、byref(n)) 

テストコードは次のようになります:

  r = numpy.zeros ((i、i)、numpy.float32)tBlas = timeit.Timer( "Mul(m1、m2、i、r)"、 "import numpy; from __main__ import i、m1、m2、r、Mul")rBlas。 append((i、tBlas.repeat(20、1))) 

3。 c ++、共有オブジェクトを介してBLASを呼び出す

これで、c ++コードは自然に少し長くなるため、情報を最小限に抑えます。
関数をロードします

  void * handle = dlopen( "libblas.so"、RTLD_LAZY); void * Func = dlsym(handle、 "sgemm_");  

次のようにgettimeofdayで時間を測定します。

  gettimeofday(& start、NULL); f(& no_trans、& no_trans、& dim、& dim、& dim、& one、A、& dim、B、& dim、& zero、Return、& dim); gettimeofday(& end、NULL); dTimes [j] = CalcTime(start、end);  

ここで、 jは20回実行されるループです。経過時間を計算します

  double CalcTime(timeval start、timeval end){double factor = 1000000; return(((double)end.tv_sec)* factor +((double)end.tv_usec)-(((double)start.tv_sec)* factor +((double)start.tv_usec)))/ factor; }  

結果

結果は次のプロットに表示されます:

ここに画像の説明を入力

質問

  1. 私のアプローチは公平だと思いますか、それとも不要なオーバーヘッドがありますか避けますか?
  2. 結果がc++とpythonのアプローチの間にこのような大きな矛盾を示すと思いますか?どちらも計算に共有オブジェクトを使用しています。
  3. プログラムにPythonを使用したいので、BLASまたはLAPACKルーチンを呼び出すときのパフォーマンスを向上させるにはどうすればよいですか?

ダウンロード

完全なベンチマークはここからダウンロードできます。 (JFセバスティアンはそのリンクを可能にしました^^)