은행 충돌이란 무엇입니까? (Cuda / OpenCL 프로그래밍 수행)


95

CUDA 및 OpenCL에 대한 프로그래밍 가이드를 읽고 있는데 은행 충돌이 무엇인지 알 수 없습니다. 그들은 주제 자체에 대해 자세히 설명하지 않고 문제를 해결하는 방법에 대해 잠수합니다. 아무도 내가 그것을 이해하도록 도울 수 있습니까? 도움이 CUDA / OpenCL의 맥락에 있거나 컴퓨터 과학의 일반적인 은행 충돌에 관한 것이라면 선호하지 않습니다.

답변:


105

nvidia (및 amd) gpus의 경우 로컬 메모리는 메모리 뱅크로 나뉩니다. 각 뱅크는 한 번에 하나의 데이터 세트 만 처리 할 수 ​​있으므로 하프 워프가 동일한 뱅크에서 데이터를로드 / 저장하려고하면 액세스를 직렬화해야합니다 (이는 뱅크 충돌입니다). gt200 gpus의 경우 16 개의 뱅크 (페르미의 경우 32 뱅크), AMD GPU의 경우 16 또는 32 개의 뱅크 (57xx 이상 : 32, 아래의 모든 것 : 16))가 있으며, 이는 32 비트 단위로 인터리브됩니다 (따라서 바이트 0-3은 뱅크 1, 뱅크 2의 4-7, ..., 뱅크 1의 64-69 등). 더 나은 시각화를 위해 기본적으로 다음과 같습니다.

Bank    |      1      |      2      |      3      |...
Address |  0  1  2  3 |  4  5  6  7 |  8  9 10 11 |...
Address | 64 65 66 67 | 68 69 70 71 | 72 73 74 75 |...
...

따라서 하프 워프의 각 스레드가 연속적인 32 비트 값에 액세스하면 뱅크 충돌이 없습니다. 이 규칙의 예외 (모든 스레드가 자체 뱅크에 액세스해야 함)는 브로드 캐스트입니다. 모든 스레드가 동일한 주소에 액세스하면 값은 한 번만 읽고 모든 스레드에 브로드 캐스트됩니다 (GT200의 경우 하프 워프의 모든 스레드가 동일한 주소, iirc fermi 및 AMD gpus는 동일한 값에 액세스하는 스레드 수에 관계없이이를 수행 할 수 있습니다.


3
비주얼과 설명에 감사드립니다. 방송에 대해 몰랐고 중요한 정보 인 것 같습니다. :) 내로드와 스토어가 공유 메모리에서 뱅크 충돌을 일으키지 않는지 확인하려면 어떻게해야합니까? 어떻게 든 어셈블리 코드를 가져와야합니까 아니면 다른 방법이 있습니까?
smuggledPancakes

3
뱅크 충돌의 발생은 런타임에 결정될 것이므로 (컴파일러가 런타임에 대부분의 주소가 생성 된 후 이에 대해 알지 못함을 의미) 컴파일 된 버전을 얻는 것이별로 도움이되지 않습니다. 저는 일반적으로이 작업을 옛날 방식대로 수행합니다. 펜과 종이를 사용하여 코드가 어디에 저장되어 있는지 생각하기 시작합니다. 결국 은행 갈등의 발생을 통제하는 규칙은 그렇게 복잡하지 않습니다. 그렇지 않으면 nvidia OpenCL 프로파일 러를 사용할 수 있습니다 (sdk, iirc와 함께 번들로 제공되어야 함). 워프 연재 카운터가 있다고 생각합니다.
Grizzly

1
워프 직렬화를 지적 해 주셔서 감사합니다. 컴퓨팅 프로파일 러와 함께 제공되는 readme 텍스트 파일 중 하나가 이렇게 말했습니다.
smuggledPancakes

1
위의 댓글을 실례합니다. 어떤 이유로 든 다시 수정할 수 없습니다. 어쨌든, 컴퓨팅 프로파일 러의 readme에서 "warp_serialize : 공유 또는 상수 메모리에 대한 주소 충돌시 직렬화하는 스레드 왜곡 수"에서 이것을 발견했습니다. 프로파일 러 출력을 보는 것만으로도 충돌이 있는지 쉽게 확인할 수 있다는 점이 좋습니다. 펜과 종이에 은행 충돌이 있는지 어떻게 알 수 있습니까? 예제 나 튜토리얼에서 배웠습니까?
smuggledPancakes

1
내가 말했듯이 주소에서 은행으로의 매핑은 상대적으로 간단하므로 어떤 액세스가 어느 은행으로 이동하는지, 따라서 은행 충돌이 있는지 파악하는 것은 그리 어렵지 않습니다. 이 문서는 더 많은 충돌 액세스 패턴에 대한 것입니다.
Grizzly

13

병렬로 액세스 할 수있는 공유 메모리는 모듈 (뱅크라고도 함)로 나뉩니다. 동일한 뱅크에서 두 개의 메모리 위치 (주소)가 발생 하면 액세스가 직렬로 수행 되는 동안 뱅크 충돌이 발생하여 병렬 액세스의 이점을 잃게됩니다.


그렇다면 이것은 하프 워프가 메모리를 저장하거나로드하려고 할 때와 관련이 있습니까? 16 개의 스레드가 메모리 트랜잭션을 시도하므로 둘 이상의 스레드로 동일한 뱅크에 액세스하면 직렬화 된 처리가 발생합니까? 또한 동일한 뱅크에 데이터를 저장 /로드하지 않는지 어떻게 확인합니까?
smuggledPancakes

10

간단히 말해서, 뱅크 충돌은 메모리 액세스 패턴이 메모리 시스템에서 사용 가능한 뱅크에 IO를 분배하지 못하는 경우입니다. 다음 예제는 개념을 자세히 설명합니다.

2 차원 512x512 정수 배열이 있고 DRAM 또는 메모리 시스템에 512 개의 뱅크가 있다고 가정 해 보겠습니다. 기본적으로 어레이 데이터는 arr [0] [0]이 뱅크 0으로, arr [0] [1]이 뱅크 1로, arr [0] [2]가 뱅크 2로 이동하는 방식으로 레이아웃됩니다. arr [0] [511]은 뱅크 511로갑니다. arr [x] [y]는 뱅크 번호 y를 차지합니다. 이제 일부 코드 (아래 그림 참조)가 열 주요 방식으로 데이터에 액세스하기 시작합니다. y를 일정하게 유지하면서 x를 변경하면 최종 결과는 모든 연속 메모리 액세스가 동일한 뱅크에 도달하므로 뱅크 충돌이 발생합니다.

int arr[512][512];
  for ( j = 0; j < 512; j++ ) // outer loop
    for ( i = 0; i < 512; i++ ) // inner loop
       arr[i][j] = 2 * arr[i][j]; // column major processing

일반적으로 이러한 문제는 배열을 버퍼링하거나 배열에서 소수의 요소를 사용하여 컴파일러에서 방지합니다.


7

(CUDA Bank Conflict) 도움이 되었으면 좋겠습니다 .. 아주 좋은 설명입니다 ...

http://www.youtube.com/watch?v=CZgM3DEBplE


1
참고 것을 링크 전용 답변 낙심, SO 응답 솔루션 (대 아직 시간이 지남에 따라 부패하는 경향 참조의 다른 경유지)에 대한 검색의 엔드 포인트이어야한다. 여기에 독립형 시놉시스를 추가하고 링크를 참조로 유지하십시오.
kleopatra 2013

OP를 더 잘 지원하기 위해 링크를 자세히 설명해주세요.
Peter Foti 2013

1
이 비디오는 정말 도움이됩니다! 그리고 나는 왜 반대표를 던 졌는지 모르겠습니다! 아주 좋은 입력입니다! +1
Gabriel

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