BLAS 및 LAPACK 선형 대수 기능을 광범위하게 사용하는 프로그램을 작성하고 싶습니다. 성능이 문제이기 때문에 벤치마킹을 했고 내가 취한 접근 방식이 합법적인지 알고 싶습니다.
말하자면 세 명의 참가자가 있고 간단한 행렬-매트릭스로 그들의 성능을 테스트하고 싶습니다. 곱셈. 참가자는 다음과 같습니다.
- Numpy는
dot
의 기능만 사용합니다. - Python은 공유 개체를 통해 BLAS 기능을 호출합니다.
- C++, 공유 객체를 통해 BLAS 기능 호출.
시나리오
다른 차원에 대한 행렬-행렬 곱셈을 구현했습니다. 나
. i
는 5에서 500까지 5씩 증가하며 실행되며 행렬 m1
및 m2
은 다음과 같이 설정됩니다.
<코드>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; }
결과
결과는 아래 플롯에 표시됩니다.
질문
- 내 접근 방식이 공정하다고 생각합니까, 아니면 내가 할 수 있는 불필요한 오버헤드가 있습니까? 피하세요?
- 결과가 C++와 python 접근 방식 사이에 그렇게 큰 불일치를 보일 것이라고 예상하셨습니까? 둘 다 계산을 위해 공유 객체를 사용하고 있습니다.
- 내 프로그램에 파이썬을 사용하고 싶기 때문에 BLAS 또는 LAPACK 루틴을 호출할 때 성능을 높이려면 어떻게 해야 합니까?
다운로드
전체 벤치마크는 여기에서 다운로드할 수 있습니다. (JF Sebastian이 그 링크를 가능하게 했습니다^^)