Я читал руководство по программированию для CUDA и OpenCL и не могу понять, что такое конфликт банков. Они просто как бы погружаются в то, как решить проблему, не углубляясь в саму тему. Может ли кто-нибудь помочь мне понять это? У меня нет предпочтений, если помощь находится в контексте CUDA/OpenCL или просто банковских конфликтов в целом в области информатики.
Что такое конфликт с банком? (Выполнение программирования Cuda/OpenCL)
Ответы (5)
Для nvidia (и amd в этом отношении) gpu локальная память разделена на банки памяти. Каждый банк может одновременно обращаться только к одному набору данных, поэтому, если полуварп пытается загрузить/сохранить данные из/в один и тот же банк, доступ должен быть сериализован (это конфликт банков). Для gt200 gpu имеется 16 банков (32 банка для fermi), 16 или 32 банка для AMD gpu (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://www.youtube.com/watch?v=CZgM3DEBplE
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...|
надеюсь, это поможет