W przypadku procesorów graficznych nvidia (i amd) pamięć lokalna jest podzielona na banki pamięci. Każdy bank może adresować tylko jeden zestaw danych na raz, więc jeśli półwarp próbuje załadować / przechowywać dane z / do tego samego banku, dostęp musi zostać serializowany (jest to konflikt banku). Dla procesorów GT200 jest 16 banków (32 banki dla procesorów Fermi), 16 lub 32 banki dla procesorów AMD (57xx lub nowszy: 32, wszystko poniżej: 16)), które są przeplatane z ziarnistością 32-bitową (więc bajty 0-3 są w bank 1, 4-7 w banku 2, ..., 64-69 w banku 1 i tak dalej). Dla lepszej wizualizacji zasadniczo wygląda to tak:
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 |...
...
Więc jeśli każdy wątek w halfwarp uzyskuje dostęp do kolejnych 32-bitowych wartości, nie ma konfliktów bankowych. Wyjątkiem od tej reguły (każdy wątek musi mieć dostęp do własnego banku) są rozgłaszania: Jeśli wszystkie wątki mają dostęp do tego samego adresu, wartość jest odczytywana tylko raz i transmitowana do wszystkich wątków (w przypadku GT200 muszą to być wszystkie wątki w półwarstwie, które mają dostęp do ten sam adres, iirc fermi i AMD gpus mogą to zrobić dla dowolnej liczby wątków uzyskujących dostęp do tej samej wartości).
Pamięć współdzielona, do której można uzyskać dostęp równolegle, jest podzielona na moduły (zwane także bankami). Jeśli dwie lokalizacje pamięci (adresy) występują w tym samym banku, pojawia się konflikt banku, podczas którego dostęp odbywa się szeregowo, tracąc zalety dostępu równoległego.
źródło
Mówiąc prościej, konflikt banków to przypadek, w którym jakikolwiek wzorzec dostępu do pamięci nie rozprowadza operacji we / wy w bankach dostępnych w systemie pamięci. Następujące przykłady rozwijają koncepcję:
Załóżmy, że mamy dwuwymiarową tablicę liczb całkowitych 512x512, a nasz DRAM lub system pamięci ma 512 banków. Domyślnie dane tablicy zostaną rozmieszczone w taki sposób, że arr [0] [0] trafia do banku 0, arr [0] [1] trafia do banku 1, arr [0] [2] do banku 2 .... arr [0] [511] trafia do banku 511. Aby uogólnić, arr [x] [y] zajmuje numer banku y. Teraz jakiś kod (jak pokazano poniżej) zaczyna uzyskiwać dostęp do danych w głównej kolumnie, tj. zmieniając x przy zachowaniu stałej y, wynikiem końcowym będzie to, że cały kolejny dostęp do pamięci trafi do tego samego banku - stąd konflikt banku.
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
Kompilatory zazwyczaj unikają takich problemów, buforując tablicę lub używając liczby pierwszej elementów tablicy.
źródło
(CUDA Bank Conflict) Mam nadzieję, że to pomoże ... to jest bardzo dobre wyjaśnienie ...
http://www.youtube.com/watch?v=CZgM3DEBplE
źródło
http://en.wikipedia.org/wiki/Memory_bank
i http://mprc.pku.cn/mentors/training/ISCAreading/1989/p380-weiss/p380-weiss.pdf
na tej stronie można znaleźć szczegółowe informacje o banku pamięci. ale różni się trochę od tego, co mówi @Grizzly. na tej stronie bank jest taki
bank 1 2 3
adres | 0, 3, 6 ... | | 1, 4, 7 ... | | 2, 5,8 ... |
mam nadzieję, że to pomoże
źródło