Доступ к объединенной памяти - это функция или явление?

В настоящее время я пишу небольшой проект в OpenCL, и я пытаюсь выяснить, что действительно вызывает объединение памяти. В каждой книге по программированию GPGPU говорится, что именно так должны программироваться GPGPU, но не то, почему аппаратное обеспечение предпочло бы это.

Так это какой-то специальный аппаратный компонент, который объединяет передачу данных? Или это просто лучше использовать кеш? Или это что-то совершенно другое?

2 ответа

Объединение памяти делает несколько разных вещей более эффективными. Обычно это делается до того, как запросы попадают в кеш. Подобно модели исполнения SIMT, это архитектурный компромисс. Это позволяет графическим процессорам иметь более эффективную и высокопроизводительную систему памяти, а также заставляет программистов тщательно продумывать расположение своих данных.

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

Объединять запросы довольно просто, вы просто выбираете одну передачу, а затем объединяете все запросы с соответствующими старшими адресными битами. Вы просто генерируете один запрос за цикл и воспроизводите инструкцию загрузки или сохранения, пока все потоки не будут обработаны.

Кэши также хранят последовательные байты, 32/64/128 байт, это хорошо подходит для большинства приложений, хорошо подходит для современных DRAM и снижает накладные расходы на информацию о поддержании кеша: кеш организован по строкам кеша, и каждая строка кеша имеет тег, который указывает, какие адреса хранятся в строке.

Современный DRAM использует широкие интерфейсы, а также длинные пакеты: память GPU обычно организована в 32-битных или 64-битных каналах с памятью GDDR5, длина пакета которой равна 8. Это означает, что каждая транзакция на интерфейсе DRAM должна извлекать по крайней мере 32-битный *8=32 байта или 64-битный *8=64 байта за раз, даже если из этих байтов требуется только один байт. Разработка макетов данных, которые приводят к объединенным запросам, помогает эффективно использовать интерфейс DRAM.

Графические процессоры также имеют огромное количество параллельных потоков, работающих одновременно, и довольно небольшой кэш в то же время. Процессоры часто могут использовать свои кэши для переупорядочения запросов к памяти в соответствии с дружественными DRAM-шаблонами. Большее количество потоков и меньший объем кэшей в графических процессорах делают это "объединение на основе кэша" менее эффективным в графических процессорах, поскольку данные часто не будут оставаться в кэше достаточно долго, чтобы объединиться в кэше с другими запросами в той же самой строке кэша.

Несмотря на имя "произвольного доступа" в "ОЗУ" (оперативное запоминающее устройство), память с произвольным доступом с двойной скоростью передачи данных №3 (DDR3-RAM) быстрее получает доступ к последовательным позициям, а не случайным образом.

Показательный пример: " Задержка CAS" - это время, в течение которого ОЗУ DDR3 останавливается, когда вы получаете доступ к новой "колонке", поскольку ваша микросхема ОЗУ буквально заряжается, чтобы обслуживать новые данные из другого местоположения на микросхеме.

РЕДАКТИРОВАТЬ: Ян Лукас утверждает, что задержка RAS является более важным на практике. Смотрите его комментарий для деталей.

При переключении столбцов задержка составляет примерно 10 нс. Итак, если у вас есть куча обращений к памяти, если вы держите доступ к куче данных "близко" друг к другу, то вы не вызываете задержку CAS.

Таким образом, если у вас есть 20 слов для доступа в определенном месте, более эффективно получить доступ к этим 20 словам перед перемещением в новую область памяти (вызывая задержку CAS). В противном случае вам придется вызывать ДРУГУЮ задержку CAS, чтобы "переключиться назад" между ячейками памяти.

Это всего около 10 наносекунд, но это время увеличивается.

Другие вопросы по тегам