2013-10-19 1 views
5

현재 여러 개의 코어로 프로그래밍하려고합니다. C++/Python/Java로 병렬 행렬 곱셈을 작성하거나 구현하고 싶습니다 (Java가 가장 단순한 것 같습니다).한 번에 하나의 CPU 만 RAM에 액세스 할 수 있습니까?

하지만 스스로 대답 할 수없는 한 가지 질문은 RAM 액세스가 여러 CPU에서 어떻게 작동하는지입니다.

내 생각

우리 두 행렬 A와 B. 우리는 C가 A *의 B를 = 산출 할 가지고

enter image description here

병렬 실행만이있을 빠르고 때 N, m 또는 p는 크다. n, m, p> = 10,000이라고 가정합니다. 간단히하기 위해 n = m = p = 10,000 = 10^4라고 가정합니다.

enter image description here

:

우리는 우리가 그래서 우리는 모든 C_ {I, J} 병렬 계산 할 수 C.의 다른 항목을보고 withouth 각 $의 C_ {I, J}를 $ 계산할 수 있다는 것을 알고 그러나 모든 c_ {1, i} (i \ in 1, ..., p)는 A의 첫 번째 줄을 필요로합니다. A가 10^8 배의 배열이기 때문에 800MB가 필요합니다. 이것은 CPU 캐시보다 확실히 큰 것입니다. 그러나 한 줄 (80kB)은 CPU 캐시에 맞습니다. 그래서 C의 모든 라인을 정확히 하나의 CPU에 할당하는 것이 좋습니다. 따라서이 CPU는 적어도 캐시에 A를 가지고 있으며 그로부터 이익을 얻습니다.

방법 RAM 액세스 (일반 인텔 노트북) 다른 코어에 대한 관리 내 질문?

한 번에 하나의 CPU에만 독점적으로 액세스 할 수있는 "컨트롤러"가 있어야합니다. 이 제어기에는 특별한 이름이 있습니까?

우연히 두 개 이상의 CPU가 동일한 정보를 필요로 할 수 있습니다. 그들은 동시에 그것을 얻을 수 있습니까? RAM 액세스가 행렬 곱셈 문제의 병목 지점입니까?

멀티 코어 프로그래밍 (C++/Python/Java)을 소개하는 좋은 책을 알고 있으면 알려주십시오.

+0

[캐시 일관성] (http://en.wikipedia.org/wiki/Cache_coherence)에 대해 배우고 싶을 수도 있습니다. –

+0

동일한 물리적 CPU의 여러 코어가 (적어도 일부) 캐시 메모리를 공유하기 때문에 멀티 코어와 멀티 CPU간에 차이점이 있습니다 (메모리 관리의 관점에서 볼 때). 코어는 모두 '문자 그대로'동시에 사용할 수는 없지만 RAM에서 읽을 수 있습니다. 다중 코어를 가진 전형적인 최신 CPU는 모든 코어에서 공유 상위 레벨 캐시를 구현합니다. – Leigh

+1

왜 바퀴를 발명하나요? :) OpenBLAS와 같은 것을 가져 와서 구현을 보지 않으시겠습니까? –

답변

3

매트릭스 곱셈을 캐시 친화적 인 방식으로 병렬 처리하는 것에 대한 질문을 분리해야합니다 (여러 가지 방법이 있습니다. "타일링"검색 here's a nice explanation from Berkeley). 여러 코어가 공유 캐시 및 메모리. 첫 번째는 캐시 스 래싱을 피할 수있는 방법과 특정 캐시 계층에서 데이터의 효과적인 재사용을 수행 할 수있는 방법을 말하며, 후자는 메모리 대역폭 사용률을 나타냅니다. 두 가지가 연결되어 있지만 실제로는 상호 배타적입니다. 좋은 캐싱은 아웃 바운드 대역폭을 줄이기 때문입니다 (물론 성능과 전력 모두에 바람직합니다). 그러나 데이터를 재사용 할 수 없거나 알고리즘을 캐시에 맞게 수정할 수없는 경우에는 수행 할 수없는 경우도 있습니다. 이 경우 메모리 BW가 병목 현상이 될 수 있으며 다른 코어는 가능한 한 최상의 상태로 공유해야합니다.

대부분의 최신 CPU에는 마지막 레벨 캐시를 공유하는 여러 코어가 있습니다. (일부 스마트 폰 세그먼트에서는 이것이 확실치 않지만 노트북/데스크톱/서버의 경우 일반적으로 적용됩니다). 그 캐시는 다시 노스 브리지라고 불리는 다른 칩에 앉아 있던 메모리 컨트롤러와 통신하지만 몇 년 전에는 더 빠른 액세스를 위해 대부분의 CPU에 통합되었다. 메모리 컨트롤러를 통해 전체 CPU가 DRAM과 통신하여 가져올 내용을 알릴 수 있습니다.MC는 대개 액세스를 결합하기에 충분히 똑똑하기 때문에 가져 오는 데 최소한의 시간과 노력이 필요합니다 (DRAM에서 "페이지"가져 오기는 긴 작업이므로 감지 증폭기에 버퍼링 된 현재 페이지를 먼저 제거해야 함)).

이 구조는 MC가 다중 코어와 별도로 통신 할 필요가 없다는 것을 의미하며, 마지막 레벨 캐시로 데이터를 가져옵니다. 코어는 마지막 레벨 캐시를 통해 액세스가 필터링되므로 메모리 컨트롤러와 직접 대화 할 필요가 없습니다. 캐시를 지나갈 수있는 캐시 할 수없는 액세스와 다른 컨트롤러가있는 IO 액세스와 같은 예외는 거의 없습니다. 모든 코어는 자체 캐시뿐만 아니라 캐시 저장소를 공유합니다.

이제 공유에 대한 참고 사항 - 2 개 이상의 코어가 동일한 데이터를 동시에 필요로하는 경우 운이 좋았습니다. 이미 캐시에 저장되어 있습니다 (이 경우 두 액세스 모두 차례대로 캐시를 전송 함). 데이터를 각 코어에 저장하고 "공유"로 표시) 또는 데이터가 존재하지 않으면 MC가 가져올 때까지 기다렸다가 한 번만 성공한 다음 계속 진행합니다. 그러나 한 번 이상 예외가있는 경우 하나 이상의 코어가 새 데이터를 해당 행 또는 일부에 기록해야합니다. 이 경우 수정자는 소유권 (RFO)에 대한 읽기 요청을 발행하여 라인 공유를 방지하고 다른 코어의 모든 복사본을 무효화합니다. 그렇지 않으면 캐시 일관성 또는 일관성을 잃을 위험이 있습니다 (하나의 코어가 오래된 데이터를 사용하거나 잘못된 메모리 순서를 인식). 이것은 병렬 알고리즘의 경쟁 조건으로 알려져 있으며 복잡한 잠금/펜싱 메커니즘의 원인입니다. 다시 말하지만 이것은 실제 RAM 액세스와 직각이며 마지막 레벨 캐시 액세스에도 동일하게 적용될 수 있습니다.