매트릭스-벡터 곱셈 스케일링이 아닌 이유는 무엇입니까?


15

긴 게시물에 대해 죄송하지만 첫 번째 이동과 관련이 있다고 생각되는 모든 것을 포함하고 싶었습니다.

내가 원하는 것

고밀도 행렬에 대한 병렬 버전의 Krylov Subspace Methods를 구현하고 있습니다. 주로 GMRES, QMR 및 CG. 나는 (프로파일 링 후) 내 DGEMV 루틴이 한심하다는 것을 깨달았다. 그래서 나는 그것을 격리함으로써 그것에 집중하기로 결정했습니다. 12 코어 시스템에서 실행하려고 시도했지만 아래 결과는 4 코어 Intel i3 랩톱에 대한 것입니다. 트렌드에는 큰 차이가 없습니다.

KMP_AFFINITY=VERBOSE출력은 여기에서 사용할 수 있습니다 .

작은 코드를 작성했습니다.

size_N = 15000
A = randomly_generated_dense_matrix(size_N,size_N); %Condition Number is not bad
b = randomly_generated_dense_vector(size_N);
for it=1:n_times %n_times I kept at 50 
 x = Matrix_Vector_Multi(A,b);
end

나는 이것이 50 번의 반복에 대한 CG의 동작을 시뮬레이션한다고 생각합니다.

내가 시도한 것 :

번역

나는 원래 포트란에서 코드를 작성했다. 나는 그것을 C, MATLAB 및 Python (Numpy)으로 번역했습니다. 말할 것도없이 MATLAB과 Python은 끔찍했습니다. 놀랍게도, C는 위의 값에 대해 FORTRAN보다 1 초 또는 2 초 더 낫습니다. 일관되게.

프로파일 링

코드를 실행하도록 프로파일 링했으며 46.075몇 초 동안 실행되었습니다 . MKL_DYNAMIC이 설정FALSE 되고 모든 코어가 사용 된 시점 입니다. MKL_DYNAMIC을 true로 사용하면 특정 시점에 코어 수의 절반 만 사용되었습니다. 다음은 몇 가지 세부 사항입니다.

Address Line    Assembly                CPU Time

0x5cb51c        mulpd %xmm9, %xmm14     36.591s

가장 시간이 많이 걸리는 프로세스는 다음과 같습니다.

Call Stack                          LAX16_N4_Loop_M16gas_1
CPU Time by Utilization             157.926s
CPU Time:Total by Utilization       94.1%
Overhead Time                       0us
Overhead Time:Total                 0.0%    
Module                              libmkl_mc3.so   

다음은 몇 가지 그림입니다.여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오

결론 :

프로파일 링의 초보자이지만 속도가 여전히 좋지 않다는 것을 알고 있습니다. 순차적 (1 코어) 코드는 53 초 안에 완료됩니다 . 그것은 1.1 이하의 속도입니다!

실제 질문 : 속도 향상을 위해 어떻게해야합니까?

도움이 될 것 같지만 확신 할 수없는 것 :

  • Pthreads 구현
  • MPI (ScaLapack) 구현
  • 수동 튜닝 (방법을 모르겠습니다. 제안하는 경우 리소스를 권장하십시오)

누구든지 (특히 메모리 관련) 세부 정보가 더 필요하면 내가 무엇을 어떻게 실행 해야하는지 알려주십시오. 나는 메모리 프로파일 링을 해본 적이 없다.

답변:


20

행렬의 크기는 15,000 x 15,000이므로 행렬에 225M 요소가 있습니다. 이것은 대략 2GB의 메모리를 만듭니다. 이것은 프로세서의 캐시 크기보다 훨씬 크기 때문에 모든 행렬 곱셈의 주 메모리에서 완전히로드되어 약 100GB의 데이터 전송과 소스 및 대상 벡터에 필요한 것을 제공해야합니다.

i3의 최대 메모리 대역은 인텔 사양에 따라 약 21GB / s이지만 웹을 살펴보면 실제로 절반 정도가 실제로 사용 가능하다는 것을 알 수 있습니다. 따라서 최소한 벤치 마크는 10 초 동안 지속될 것으로 예상되며 실제 45 초 측정은 그 정도를 벗어나지 않습니다.

동시에, 당신은 또한 약 100 억 개의 부동 소수점 곱셈을 추가하고 있습니다. 예를 들어, 조합을위한 10 클럭 사이클과 3 GHz 클럭 속도를 고려하면 ~ 30 초에 나옵니다. 물론 캐시가 영리한 경우에는 추론 적 메모리로드와 동시에 실행할 수 있습니다.

전체적으로, 나는 당신이 그 마크에서 너무 멀지 않다고 말하고 싶습니다. 무엇을 기대 했습니까?


2-3 배의 속도를 올리는 방법이 없습니까?
Inquest

@Nunoxic-SiSoftware Sandra와 같은 도구를 사용하여 시스템의 메모리 성능을 벤치 마크 할 수 있습니다. Wolfgangs 분석은 나에게 주목됩니다. 응용 프로그램이 메모리 대역폭에 묶여 있으면 병렬화는 거의 도움이되지 않습니다. 또한 전원 절약 옵션을 살펴보십시오. 메모리 성능이 저하 될 수 있습니다. 또한 메모리를 더 높은 품질의 메모리로 교체하는 것을 고려하십시오. 예를 들어 CAS 대기 시간이 짧을수록 사용 시간이 크게 달라질 수 있습니다.
Mark Booth

4

행렬-벡터 곱셈은 어떻습니까? 손으로 이중 루프? 아니면 BLAS에 전화? MKL을 사용하는 경우 스레드 버전의 BLAS 루틴을 사용하는 것이 좋습니다.

호기심으로, 당신은 또한 ATLAS 의 자신의 튜닝 버전을 컴파일 하고 그것이 문제에 어떻게 작동하는지 볼 수 있습니다.

최신 정보

아래 의견에 대한 논의에 따라 인텔 코어 i3-330M에는 두 개의 "실제"코어 만있는 것으로 나타났습니다. 누락 된 두 코어는 하이퍼 스레딩 으로 에뮬레이트됩니다 . 하이퍼 스레드 코어에서는 메모리 버스와 부동 소수점 장치가 모두 공유되므로 두 가지 중 하나가 제한 요소 인 경우 속도가 향상되지 않습니다. 실제로 4 개의 코어를 사용하면 속도가 느려질 수 있습니다.

두 가지 코어 만 "어떤"결과를 얻습니까?


ATLA, GoTo 및 Netlib BLAS를 시도했습니다. 모두 성능면에서 MKL보다 약합니다. 이것이 예상 되는가 아니면 내가 잘못하고 있는가? 핸드북에 언급 된대로 ATLAS를 컴파일했습니다. 또한, (정확한) 코드를 여기에 붙여 넣었 습니다 . MKL의 BLAS라고 부릅니다.
Inquest

그리고 스케일링의 경우 기본 사례에서 코드가 단일 CPU에서만 실행되고 있습니까? 예를 들어 벤치마킹하면 CPU 사용 히스토그램에 단일 코어 만 표시됩니까?
Pedro

예. CPU 히스토그램은 1 코어를 보여줍니다.
Inquest

다시 호기심에서 두 개 또는 세 개의 핵심에 대해 무엇을 얻습니까? 머신에 실제로 4 개의 물리적 코어가 있거나 하이퍼 스레딩이 있는 2 개의 코어가 있습니까?
Pedro

어떻게 알 수 있습니까? KMP_AFFINITY를 메인에 포함 시켰습니다.
Inquest

0

메모리 액세스 시간, 캐시 라인 사용 및 TLB 누락과 관련 하여이 문제에 대해 행 주요 순서가 최적이라는 인상을 받았습니다. FORTRAN 버전이 열 주요 순서를 대신 사용하여 C 버전보다 지속적으로 느린 이유를 설명 할 수 있습니다.

행렬 벡터 곱셈 대신 단일 루프에서 행렬의 모든 요소를 ​​요약하면 속도를 테스트 할 수도 있습니다. (추가의 비 연관성이 컴파일러가이 최적화를 수행하지 못하게 할 수 있기 때문에 루프를 인자 4만큼 풀릴 수 있습니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.