벤치마킹(BLAS를 사용하는 Python 대 C++) 및 (numpy)

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

BLAS 및 LAPACK 선형 대수 기능을 광범위하게 사용하는 프로그램을 작성하고 싶습니다. 성능이 문제이기 때문에 벤치마킹을 했고 내가 취한 접근 방식이 합법적인지 알고 싶습니다.

말하자면 세 명의 참가자가 있고 간단한 행렬-매트릭스로 그들의 성능을 테스트하고 싶습니다. 곱셈. 참가자는 다음과 같습니다.

  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) 하나 = c_float(1.0) 0 = 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)", "numpy 가져오기, __main__에서 가져오기 i, m1, m2, r, Mul") rBlas. 추가((i, tBlas.repeat(20, 1))) 

3. C++, 공유 객체를 통해 BLAS 호출

이제 C++ 코드는 자연스럽게 조금 길어지므로 정보를 최소한으로 줄입니다.
함수를 로드합니다.

 무효 * 핸들 = dlopen("libblas.so", RTLD_LAZY); 무효* Func = dlsym(핸들, "sgemm_"); 

다음과 같이 gettimeofday로 시간을 측정합니다.

gettimeofday(&start, NULL); f(&no_trans, &no_trans, &dim, &dim, &dim, &one, A, &dim, B, &dim, &0, Return, &dim); gettimeofday(&end, NULL); dTimes[j] = CalcTime(시작, 종료); 

여기서 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; } 

결과

결과는 아래 플롯에 표시됩니다.

enter image description here

질문

  1. 내 접근 방식이 공정하다고 생각합니까, 아니면 내가 할 수 있는 불필요한 오버헤드가 있습니까? 피하세요?
  2. 결과가 C++와 python 접근 방식 사이에 그렇게 큰 불일치를 보일 것이라고 예상하셨습니까? 둘 다 계산을 위해 공유 객체를 사용하고 있습니다.
  3. 내 프로그램에 파이썬을 사용하고 싶기 때문에 BLAS 또는 LAPACK 루틴을 호출할 때 성능을 높이려면 어떻게 해야 합니까?

다운로드

전체 벤치마크는 여기에서 다운로드할 수 있습니다. (JF Sebastian이 그 링크를 가능하게 했습니다^^)