Что такое банковский конфликт? (Занимаюсь программированием на Cuda/OpenCL)
Я читал руководство по программированию для CUDA и OpenCL, и я не могу понять, что такое банковский конфликт. Они просто погружаются в то, как решить проблему, не углубляясь в сам предмет. Кто-нибудь может помочь мне понять это? У меня нет никакого предпочтения, если помощь находится в контексте CUDA/OpenCL или только банковские конфликты в целом в области компьютерных наук.
5 ответов
Для NVIDIA (и AMD в этом отношении) Gpus локальная память делится на банки памяти. Каждый банк может обращаться только к одному набору данных за раз, поэтому, если полуверст пытается загрузить / сохранить данные из / в один и тот же банк, доступ должен быть сериализован (это конфликт банка). Для gt200 gpus существует 16 банков (32 банка для fermi), 16 или 32 банка для AMD gpus (57xx или выше: 32, все ниже: 16)), которые чередуются с гранулярностью 32 бита (поэтому байты 0-3 находятся в банк 1, 4-7 в банке 2, ..., 64-69 в банке 1 и т. д.). Для лучшей визуализации это в основном выглядит так:
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 могут сделать это для любого количества потоков, имеющих одно и то же значение).
Общая память, к которой можно получить доступ параллельно, делится на модули (также называемые банками). Если две ячейки памяти (адреса) находятся в одном и том же банке, возникает конфликт между банками, при котором доступ осуществляется последовательно, теряя преимущества параллельного доступа.
Проще говоря, конфликт банков - это случай, когда какой-либо шаблон доступа к памяти не может распределить ввод-вывод между банками, доступными в системе памяти. Следующие примеры развивают концепцию:
Предположим, у нас есть двумерный массив целых чисел 512x512, а в нашей системе DRAM или памяти содержится 512 банков. По умолчанию данные массива будут расположены таким образом, что arr[0][0] переходит в банк 0, arr[0][1] переходит в банк 1, arr[0][2] в банк 2 ....arr[0][511] переходит к банку 511. Для обобщения arr[x][y] занимает номер банка y. Теперь некоторый код (как показано ниже) начинает доступ к данным в основной колонке, т.е. изменение x при сохранении постоянной y приведет к тому, что весь последующий доступ к памяти будет попадать в один и тот же банк - следовательно, возник конфликт банков.
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...|
надеюсь, это поможет