Почему память CUDA так быстро закреплена?

84

Я наблюдаю значительное ускорение передачи данных, когда использую закрепленную память для передачи данных CUDA. В Linux основным системным вызовом для достижения этой цели является mlock. На странице руководства mlock говорится, что блокировка страницы предотвращает ее замену:

mlock () блокирует страницы в диапазоне адресов, начиная с addr и продолжая len байтов. Все страницы, которые содержат часть указанного диапазона адресов, гарантированно будут резидентными в ОЗУ после успешного возврата вызова;

В моих тестах у меня было несколько гигов свободной памяти в моей системе, поэтому никогда не было никакого риска, что страницы памяти могли быть выгружены, но я все же наблюдал ускорение. Может ли кто-нибудь объяснить, что здесь происходит на самом деле? Любое понимание или информация очень ценятся.

Героид Мерфи
источник
Время самого млока замеряли?
osgx
Нет, предполагается, что фактическое время, затраченное на выполнение вызова mlock, незначительно (если это то, о чем вы спрашиваете). Реальные накладные расходы - это фактическая передача данных, которая в моем алгоритме составляет значительную часть от общего времени цикла.
Gearoid Мерфи
Какой у вас процессор? Возможно, узлы с поддержкой NUMA не выиграют от простого mlock().
osgx
Процессор AMD Phenom (tm) II X4 970
Gearoid Murphy

Ответы:

85

Драйвер CUDA проверяет , заблокирован ли диапазон памяти или нет, и затем будет использовать другой путь кода. Заблокированная память хранится в физической памяти (ОЗУ), поэтому устройство может извлекать ее без помощи ЦП (DMA, также известное как Async copy; устройству нужен только список физических страниц). Незаблокированная память может генерировать ошибку страницы при доступе, и она сохраняется не только в памяти (например, она может быть в свопинге), поэтому драйверу необходимо получить доступ к каждой странице незаблокированной памяти, скопировать ее в закрепленный буфер и передать ее в DMA (синхронное, постраничное копирование).

Как описано здесь http://forums.nvidia.com/index.php?showtopic=164661

Память хоста, используемая вызовом асинхронного копирования памяти, должна быть заблокирована по страницам с помощью cudaMallocHost или cudaHostAlloc.

Я также могу порекомендовать проверить руководства cudaMemcpyAsync и cudaHostAlloc на сайте developer.download.nvidia.com. HostAlloc говорит, что драйвер cuda может обнаруживать закрепленную память:

Драйвер отслеживает диапазоны виртуальной памяти, выделенные этой функцией (cudaHostAlloc), и автоматически ускоряет вызовы таких функций, как cudaMemcpy ().

osgx
источник
1
Интересно, сколько разрушения вы можете создать, если другой поток попытается разблокировать страницы после выполнения команд асинхронного копирования?
Zan Lynx
1
Zan Lynx, Интересный вопрос. Почему вы хотите разблокировать эту память? Может быть до 2-4 ГБ заблокированной памяти даже на 32-битном ПК, и больше, когда карта PCI-express имеет доступ к 64-битному (реально 40 или 48 битному) адресу. Гораздо дешевле купить больше памяти, чем платить за программиста с истекшим сроком годности (18 тыс. Репутации! На SO). Как и в Linux, я думаю (верю), что munlock будет заблокирован или вернет ошибку, и система не пострадает.
osgx
Могу ли я обратиться cudaHostRegisterк указателю на файл с отображением памяти?
Томилов Анатолий
16

CUDA использует DMA для передачи закрепленной памяти на GPU. Страничная память хоста не может использоваться с DMA, потому что она может находиться на диске. Если память не закреплена (т. Е. Страничная блокировка), она сначала копируется в «промежуточный» буфер с блокировкой страницы, а затем копируется в графический процессор через DMA. Таким образом, используя закрепленную память, вы экономите время на копирование из страничной памяти хоста в страничную память хоста.

Шен Ян
источник
5

Если страницы памяти еще не были доступны, они, вероятно, никогда не менялись местами с самого начала . В частности, вновь выделенные страницы будут виртуальными копиями универсальной «нулевой страницы» и не будут иметь физического экземпляра, пока они не будут записаны. Новые карты файлов на диске также останутся только на диске до тех пор, пока они не будут прочитаны или записаны.

R .. GitHub НЕ ПОМОГАЕТ ICE
источник
Я думаю, что это не так (я пишу об этом в раннем варианте своего ответа), так как это настоящая программа, и она mlock()была быстрой в программе (проверьте комментарий № 2 к Q).
osgx