답변:
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는 동일한 값에 액세스하는 스레드 수에 관계없이이를 수행 할 수 있습니다.
병렬로 액세스 할 수있는 공유 메모리는 모듈 (뱅크라고도 함)로 나뉩니다. 동일한 뱅크에서 두 개의 메모리 위치 (주소)가 발생 하면 액세스가 직렬로 수행 되는 동안 뱅크 충돌이 발생하여 병렬 액세스의 이점을 잃게됩니다.
간단히 말해서, 뱅크 충돌은 메모리 액세스 패턴이 메모리 시스템에서 사용 가능한 뱅크에 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
일반적으로 이러한 문제는 배열을 버퍼링하거나 배열에서 소수의 요소를 사용하여 컴파일러에서 방지합니다.
(CUDA Bank Conflict) 도움이 되었으면 좋겠습니다 .. 아주 좋은 설명입니다 ...
http://en.wikipedia.org/wiki/Memory_bank
및
http://mprc.pku.cn/mentors/training/ISCAreading/1989/p380-weiss/p380-weiss.pdf
이 페이지에서 메모리 뱅크에 대한 세부 정보를 찾을 수 있습니다. 하지만 @Grizzly가 말한 것과는 조금 다릅니다. 이 페이지에서 은행은 이렇게
뱅크 1 2 3
주소 | 0, 3, 6 ... | | 1, 4, 7 ... | | 2, 5,8 ... |
이것이 도움이 되길 바랍니다