2014-11-24 2 views
1

방금 ​​행렬 * 행렬 곱셈을 LAPACK/BLAS로 한 번 실행하고 맞춤 루프 최적화 (바둑판 식)로 한 번 실행했습니다. 간단한 루프 타일링 방식이 BLAS 알고리즘보다 약 43 % 빠르기 때문에 조금 자극적입니다. 기본적으로, 제 질문은 BLAS 루틴을 실수로 적용하는지 여부입니다. 여기 내 코드는 다음과 같습니다.LAPACK/BLAS sgemm() 맞춤 행렬 곱셈보다 느림

program test 
    implicit none 

    integer, parameter :: N = 1000, tile = 2 
    real*4, dimension(N,N) :: a,b,c,temp 
    integer :: i,j,k,x,y,z 
    double precision :: E,S 
    real :: alpha = 1.0, beta = 0.0 

    call random_seed() 
    call random_number(a) 
    call random_number(b) 

    call cpu_time(S) 

    ! call sgemm('n','n',N, N, N, alpha,a,N,b,N, beta,c,N) 

    do j = 1,N,tile 
    do k = 1,N,tile 
     do i = 1,N,tile 
      do y = j, min(j+tile-1,N) 
       do x = i, min(i+tile-1,N) 
       do z = k, min(k+tile-1,N) 
        c(x,y) = c(x,y) + a(x,z) * b(z,y) 
       enddo 
       enddo 
      enddo 
     enddo 
    enddo 
    enddo 

    call cpu_time(E) 
    print*,(E-S) 
end program test 

이 계산은 4gb DRAM 및 3096kb 캐시가있는 Intel Dual Core2 시스템에서 실행됩니다. 그래서 내가 뭔가 (컴파일러 최적화를 놓친 거지, BLAS에 대해 뭔가를받지 못하고, 또는 잘 난 그냥 모르는 오전

$gfortran test.f03 -lblas -O3 -o test 
1.3399 

:

$gfortran -O3 test.f03 -o test 
0.9359 
루프에 대한

과 :이 프로그램은 컴파일 뭐)? Eigen :: Matrix의 유무에 관계없이 C++과 유사한 코드를 실행했고 MMML에 Eigen 라이브러리를 사용함으로써 상당한 이득을 얻었습니다. 이것이 내 기대가 BLAS 라이브러리와 비슷했던 이유입니다.

답변

1

BLAS 루틴이 올바르게 사용되었습니다. 유일한 차이는 BLAS는 CPU의 캐시 메모리의 사용을 개선하기 위해 노력하고있다 루프에서

C = C + A*B 

C = 0.0*C + 1.0*A*B 

을 수행하고 루프된다는 점이다. 유사한 작업을 수행하는 BLAS의 변형이 있습니다. openblas, atlas 또는 mkl (인텔 컴파일러) 라이브러리를 사용해 보시기 바랍니다. 좋은 시간 개선을 얻을 것입니다.

+0

귀하의 의견에 감사드립니다. 방금 라이브러리로 시작했기 때문에 확실하지 않았습니다. 설명서에 약간 혼란 스러웠습니다. 하지만 제대로 구현했다면 괜찮습니다. 다시 한번 감사드립니다. – Vincent

+0

좋은 ATLAS 문서를 권장 할 수 있습니까? – Vincent

+0

ATLAS는 자동으로 튜닝 된 라이브러리의 약자입니다. 사용법은 BLAS와 동일합니다. PC에 다운로드하여 컴파일하면됩니다. 또한 오픈 블라스트는 매우 활동적인 프로젝트입니다. 또한 쉽게 만들 수 있습니다. – ztik