В устройствах CUDA объединение операций записи в глобальную память так же важно, как объединение операций чтения глобальной памяти? Если да, то как это можно объяснить? Также есть ли различия между ранними поколениями устройств CUDA и самыми последними в отношении этой проблемы?
Объединение памяти при глобальных операциях записи
Ответы (2)
Объединенные записи (или их отсутствие) могут влиять на производительность, так же как и объединенные чтения (или их отсутствие).
Объединенное чтение происходит, когда запрос на чтение инициируется командой деформации, например:
int i = my_int_data[threadIdx.x+blockDim.x*blockIdx.x];
может быть удовлетворено одной транзакцией read в контроллере памяти (что, по сути, означает, что все операции чтения отдельных потоков происходят из одной строки кэша).
Объединенная запись происходит, когда запрос на запись инициируется командой деформации, например:
my_int_data[threadIdx.x+blockDim.x*blockIdx.x] = i;
может быть выполнено одной транзакцией write в контроллере памяти.
Для приведенных выше примеров, которые я показал, нет различий между поколениями.
Но есть и другие типы операций чтения или записи, которые могут объединяться (т. е. сворачиваться в единую транзакцию контроллера памяти) на более поздних устройствах, но не на более ранних. Одним из примеров является «широковещательное чтение»:
int i = my_int_data[0];
В приведенном выше примере все потоки читаются из одного и того же глобального местоположения. В более новых устройствах такое чтение будет «рассылаться» всем потокам в одной транзакции. В некоторых более ранних устройствах это приводило к сериализованному обслуживанию потоков. Такой пример, вероятно, не имеет последствий в записи, потому что несколько потоков, записывающих в одно место, дают неопределенное поведение. Однако «зашифрованная» запись может объединяться на более новых устройствах, но не на более старых:
my_int_data[(threadIdx.x+5)%32] = i;
Обратите внимание, что все описанные выше операции записи уникальны (внутри варпа) и принадлежат отдельной строке кэша, но они не удовлетворяют требованиям объединения на устройствах 1.0 или 1.1, но должны выполняться на более новых устройствах.
Если вы читали глобальную память описание доступа для устройств cc 1.0 и 1.1 и сравнение с более поздними устройствами, вы увидите некоторые требования для объединения на более ранних устройствах, которые были ослаблены на более поздних устройствах.
Мы провели этот эксперимент на курсе, который я проводил. Объединение оказалось более важным при записи, чем при чтении, возможно, потому, что кэши L1 и L2 хранят часть неиспользуемых данных для последующего использования.