CUDA: могут ли разные потоки одновременно считывать данные из одной и той же ячейки памяти?

#memory #cuda

#память #cuda

Вопрос:

Я пишу программу CUDA для NVIDIA Tesla C2050, где каждый поток должен считывать строку символов упорядоченным образом от позиции 0 до n-1. Размер строки невелик, поэтому она может легко поместиться в постоянную, общую или текстурную память.

Мой вопрос: будут ли разные потоки обращаться к строке одновременно в одно и то же время или последовательно? Похоже, это повлияет на время выполнения моей программы.

Ответ №1:

Ответ будет «Да и нет». Это зависит от типа памяти.

Как прокомментировал @Jawad, текстурная память кэшируется, но я не совсем уверен, заполняется ли чтение одновременно или оно сериализуется и считывается из кэш-памяти.

С другой стороны, постоянная память транслируется, когда потоки в полуперестроечном режиме считывают данные из одного и того же местоположения, но при чтении из нескольких местоположений она сериализуется. Этот тип памяти также кэшируется.

Наконец, разделяемая память сериализуется, если некоторые потоки пытаются прочитать один и тот же банк памяти, также известный как конфликт банка, но * может транслироваться в несколько потоков одновременно при обслуживании одного запроса на чтение памяти *.

И это также зависит от вычислительных возможностей вашей графической карты. Я рекомендую вам ознакомиться с Руководством по программированию NVIDIA CUDA C (v.3.2 — глава приложения G., разделы G.3 Вычислительные возможности 1.x и G.4 Вычислительные возможности 2.x).

Надеюсь, это поможет.

Комментарии:

1. Я просто хочу добавить, что в отношении кэшей это также зависит от вашего шаблона доступа. Предполагая, что это Fermi, если ваши данные могут помещаться в L1 большую часть времени, у вас не будет сериализации (потоки внутри деформации, которые необходимо выполнять последовательно из-за промахов кэша). Кроме того, насколько я знаю, доступ к одной и той же строке кэша немного быстрее, чем доступ к разным строкам кэша в Fermi. То же самое, что вам нужно было бы сделать для L2.

Ответ №2:

Сопоставьте память как текстуру, и драйвер автоматически кэширует чтения, т.Е. Если несколько потоков попытаются выполнить чтение из одной глобальной позиции, будет только один вызов глобальной памяти.