Как избежать пропусков TLB (и высоких издержек глобального воспроизведения памяти) в графических процессорах CUDA?

Название может быть более конкретным, чем моя настоящая проблема, хотя я полагаю, что ответ на этот вопрос решит более общую проблему, а именно: как уменьшить эффект высокой задержки (~700 циклов), который происходит от случайного (но объединенного) глобального доступ к памяти в графических процессорах.

В общем, если кто-то обращается к глобальной памяти с объединенной нагрузкой (например, я читаю 128 последовательных байтов), но с очень большим расстоянием (256КБ-64МБ) между объединенными обращениями, он получает высокую частоту пропадания TLB (трансляционный буфер взгляда). Эта высокая частота пропусков TLB обусловлена ​​ограниченным количеством (~512) и размером (~4 КБ) страниц памяти, используемых в таблице поиска TLB.

Я предполагаю высокую частоту пропусков TLB из-за того факта, что NVIDIA использует виртуальную память, того факта, что я получаю высокие (98%) издержки Global Memory Replay и низкую пропускную способность (45 ГБ / с, с K20c) в профилировщике и Тот факт, что раздел кемпинга не является проблемой, так как Ферми.

Можно ли как-то избежать высокой частоты пропусков TLB? Поможет ли кеширование трехмерных текстур, если я получу доступ к кубу (X x Y x Z), объединившемуся вдоль измерения X и с "* шагом" X*Y вдоль измерения Z?

Любые комментарии по этой теме приветствуются.

Ограничения: 1) глобальные данные не могут быть переупорядочены / транспонированы; 2) ядро ​​связано связью.

1 ответ

Вы можете избежать промахов TLB только путем изменения схемы доступа к памяти. В этом может помочь другой формат ваших данных в памяти.
Трехмерная текстура не улучшит вашу ситуацию, поскольку она меняет улучшенную пространственную локальность в двух дополнительных измерениях против уменьшенной пространственной локальности в третьем измерении. Таким образом, вы будете без необходимости читать данные соседей по оси Y.

Однако вы можете смягчить влияние результирующей задержки на пропускную способность. Чтобы скрыть t = 700 циклов задержки при глобальной пропускной способности памяти b = 250 ГБ / с, необходимо иметь транзакции памяти для b / t = 175 КБ данных в полете в любое время (или 12,5 КБ для каждого из 14 SMX). Однако при полностью загруженном интерфейсе памяти и большом числе пропусков TLB вы обнаружите, что задержка приближается к 2000 циклам, что требует примерно 32 КБ транзакций в полете на см.

Поскольку каждое слово транзакции чтения из памяти в полете требует один регистр, в котором значение будет сохранено после его поступления, сокрытие задержки памяти должно быть балансом против давления в регистре. Для хранения 32 КБ данных в полете требуется 8192 регистра, или 12,5% от общего количества регистров, доступных на SMX.

(Обратите внимание, что для грубых оценок, приведенных выше, я пренебрег разницей между KiB и KB).

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