2014-08-28 2 views
1

두 개의 큰 행렬의 내적을 계산하려고합니다. 내적 계산을 시도 할 때 numpy 행렬의 복사본을 만들면 메모리 문제가 발생합니다. 인터넷 검색 후 numba 패키지가 유망한 것으로 나타났습니다. 그러나 제대로 작동하게 만들 수는 없습니다.numba로 내부 제품을 계산하는 정확한 방법

import numpy as np 
from numba import jit 
import time, contextlib 



@contextlib.contextmanager 
def timeit(): 
    t=time.time() 
    yield 
    print(time.time()-t,"sec") 


def dot1(a,b): 
    return np.dot(a,b) 

@jit(nopython=True) 
def dot2(a,b): 
    n = a.shape[0] 
    m = b.shape[1] 
    K = b.shape[0] 
    c = np.zeros((n,m)) 
    for i in xrange(n): 
     for j in xrange(m): 
      for k in range(K): 
       c[i,j] += a[i,k]*b[k,j] 

    return c 



def main(): 
    a = np.random.random((200,1000)) 
    b = np.random.random((1000,400)) 

    with timeit(): 
     c1 = dot1(a,b) 
    with timeit(): 
     c2 = dot2(a,b) 

다음 실행 시간 :

dot1: 
(0.034691810607910156, 'sec') 

dot2: 
(0.9215810298919678, 'sec') 

할 수있는 사람이 내가 여기에 놓친 거지 걸 알려줍니다 여기 내 코드는?

+0

그것은 그 가능성이 높습니다 행렬 곱셈은 이미 CPU 캐시/벡터 최적화를 사용하여 후드 아래에서 너무 많이 (C 또는 FORTRAN으로) 최적화되어 있으므로 JIT 컴파일이이를 초과 할 수 없습니다. – Evert

+0

메모리 요구 사항을 살펴 봤지만'np.dot'를 실행하는 동안 매트릭이 중복되었다는 어떠한 증거도 보이지 않습니다. 약간의 오버 헤드가있을 수 있지만 (필자는 그다지 깊이 파고 들지 못했지만) 확실히 두 배의 메모리가 필요하지는 않습니다. – Evert

+0

@Evert http://wiki.scipy.org/PerformanceTips의 '대 선형 대수 선형 (Linear Algebra on Large Arrays)'섹션을 살펴보십시오. 거기에 언급되어 있습니다 :'C는 40 x 40 밖에 안되지만 점의 작동 중에 메모리 사용량을 검사하면 복사본이 만들어지고 있음을 알 수 있습니다. 그 이유는 내적 제품이 인접한 C 순서로 저장된 행렬에 의존하는 기본 BLAS 연산을 사용하기 때문입니다. – Moj

답변

0

귀하의 알고리즘은 알기 쉬운 알고리즘입니다. BLAS는 더 빠른 것을 구현합니다.

인용 위키 피 디아의 matrix multiplication 페이지 : 그럼에도 불구하고

, 그러한 그 크기와 행렬에 대한 훨씬 더 효율적입니다 BLAS, 같은 몇 가지 라이브러리에 나타납니다 N> 100

관련 문제