Почему среда выполнения Cuda резервирует виртуальную память 80 гигабайт при инициализации?

Я профилировал свою программу Cuda 4, и оказалось, что на каком-то этапе запущенный процесс использовал более 80 гигабайт виртуальной памяти. Это было намного больше, чем я ожидал. Изучив эволюцию карты памяти с течением времени и сравнивая, какую строку кода она выполняет, оказалось, что после этих простых инструкций использование виртуальной памяти увеличилось до 80 GiB:

  int deviceCount;
  cudaGetDeviceCount(&deviceCount);
  if (deviceCount == 0) {
    perror("No devices supporting CUDA");
  }

Ясно, что это первый вызов Cuda, поэтому инициализируется среда выполнения. После этого карта памяти выглядит (усечена):

Address           Kbytes     RSS   Dirty Mode   Mapping
0000000000400000   89796   14716       0 r-x--  prg
0000000005db1000      12      12       8 rw---  prg
0000000005db4000      80      76      76 rw---    [ anon ]
0000000007343000   39192   37492   37492 rw---    [ anon ]
0000000200000000    4608       0       0 -----    [ anon ]
0000000200480000    1536    1536    1536 rw---    [ anon ]
0000000200600000 83879936       0       0 -----    [ anon ]

Теперь эта огромная область памяти отображается в пространство виртуальной памяти.

Хорошо, это, может быть, не большая проблема, поскольку резервирование/выделение памяти в Linux мало что делает, если вы на самом деле не пишете в эту память. Но это действительно раздражает, поскольку, например, задания MPI должны быть указаны с максимальным объемом vmem, который может быть использован при работе. И 80GiB, это только нижняя граница, то для рабочих мест Cuda - нужно также добавить все остальные вещи.

Я могу себе представить, что это связано с так называемым "царапин", которое поддерживает Куда. Вид пула памяти для кода ядра, который может динамически расти и сокращаться. Но это спекуляция. Также он выделяется в памяти устройства.

Любые идеи?

Ответ 1

Ничто не связано с пространством царапин, это результат системы адресации, которая позволяет унифицировать andressing и равноправный доступ между хостом и несколькими GPU. Драйвер CUDA регистрирует всю память GPU (память) + память хоста в одном виртуальном адресном пространстве, используя систему виртуальной памяти ядра. На самом деле это не потребление памяти, это просто "трюк", чтобы отобразить все доступные адресные пространства в линейное виртуальное пространство для унифицированной адресации.