У меня есть ядро, которое использует около 2 ГБ локальной памяти. Мой cudaMalloc
который пытается выделить 2.5 ГБ памяти, сработает, если я запустил этот kernel_func
раньше.
Я узнал, что память 2 ГБ по-прежнему занята после завершения работы kernel_func
, которая оставляет только 1,5 ГБ для моего cudaMalloc
. Кто-нибудь имеет решение или объяснение?
Я знаю, что использование глобальной памяти для kernel_func
может решить проблему, но по какой-то причине мне нужно использовать локальную память для этого огромного локального статического массива.
__global__ kernel_func() {
// The huge static array goes here
short my_array[50000];
}
int main() {
kernel_func<<<64, 128>>>();
// my_array is still occupying memory are this point
// This cudaMalloc will fail with insufficient memory
cudaMalloc(/* 2.5GB data */);
}
Если вы позволите завершить kernel_func
(например, с помощью cudaDeviceSynchronize()
), то я сомневаюсь, что my_array
все еще "занимает память", как вы предлагаете, после завершения работы ядра, то есть в момент этого комментария:
// my_array is still occupying memory are this point
Вы можете быть более уверенным с помощью вызова cudaMemGetInfo() в этот момент.
Тем не менее, вероятно, что вы испытываете какую-то фрагментацию памяти.
Единственный способ, которым я знаю, для "очистки листа" - это вызов cudaDeviceReset()
в этот момент. Однако это уничтожит все операции, а также любые выделения на GPU, поэтому вы должны делать это только тогда, когда у вас нет никаких других действий с GPU, и вы должны перераспределять любые данные GPU, которые вам нужны после вызова cudaDeviceReset()
.
Конечно, если вы можете организовать распределение с помощью cudaMalloc
, это может быть проще.
Обратите внимание, что одной функции cudaDeviceReset()
недостаточно для восстановления надлежащего функционального поведения графического процессора. Для этого процесс "владения" также должен быть прекращен. Смотрите здесь