В C / C ++ вы можете динамически выделять блок памяти во время выполнения, вызывая функцию malloc
.
int * h_array
h_array = malloc(sizeof(int))
Функция malloc
возвращает адрес выделенного блока памяти, который может быть сохранен в переменной какого-либо указателя.
Распределение памяти в CUDA немного отличается в двух отношениях,
-
cudamalloc
возвращает целое число в качестве кода ошибки вместо
указатель на блок памяти.
В дополнение к размеру байта
выделенный, cudamalloc
также требует двойной указатель void в качестве его
первый параметр.
int * d_array
cudamalloc ((void **) & d_array, sizeof (int))
Причина первого различия состоит в том, что все функции API CUDA следуют соглашению о возврате целочисленного кода ошибки. Таким образом, для обеспечения согласованности API cudamalloc
также возвращает целое число.
Требования к двойному указателю в качестве первого аргумента функции можно понять в два этапа.
Во-первых, поскольку мы уже решили сделать так, чтобы cudamalloc возвращал целочисленное значение, мы больше не можем использовать его для возврата адреса выделенной памяти. В Си единственный способ взаимодействия функции - это передача указателя или адреса функции. Функция может вносить изменения в значение, хранящееся по адресу или адресу, на который указывает указатель. Изменения этих значений могут быть впоследствии извлечены за пределы области действия функции с использованием того же адреса памяти.
как работает двойной указатель
Следующая диаграмма иллюстрирует, как это работает с двойным указателем.
int cudamalloc((void **) &d_array, int type_size) {
*d_array = malloc(type_size)
return return_code
}
Зачем нам нужен двойной указатель? Почему это работает
Обычно я живу в мире питонов, поэтому я также пытался понять, почему это не сработает.
int cudamalloc((void *) d_array, int type_size) {
d_array = malloc(type_size)
...
return error_status
}
Так почему же это не работает? Потому что в C, когда вызывается cudamalloc
, создается локальная переменная с именем d_array, которой присваивается значение первого аргумента функции. Мы не можем получить значение в этой локальной переменной за пределами области действия функции. Вот почему нам нужен указатель на указатель здесь.
int cudamalloc((void *) d_array, int type_size) {
*d_array = malloc(type_size)
...
return return_code
}