Выделение большего объема памяти существующему глобальному массиву памяти

#memory-mana&ement #cuda

#управление памятью #cuda

Вопрос:

возможно ли добавить память к ранее выделенному массиву в глобальной памяти?

что мне нужно сделать, так это:

 //cudamalloc memory for d_A
int n=0;int N=100;
do
{
 Kernel<<< , &&t;&&t;&&t; (d_A,n  );
 //add N memory to d_A
 while(n!=5)}
  

удаляет ли выполнение другого cudamalloc значения ранее выделенного массива? в моем случае значения предыдущего выделенного массива должны быть сохранены…

Комментарии:

1. если вас не очень устраивают malloc, realloc и free (и это лишь некоторые из них) на c, вы обнаружите невозможность написания программ на CUDA. по одной вещи за раз!!

Ответ №1:

Во-первых, cudaMalloc ведет себя как malloc, а не realloc. Это означает, что cudaMalloc выделит совершенно новую память устройства в новом месте. В cuda API отсутствует функция realloc.

Во-вторых, в качестве обходного пути вы можете просто снова использовать cudaMalloc для выделения большего объема памяти. Не забудьте освободить указатель устройства с помощью cudaFree, прежде чем назначать новый адрес d_a . Следующий код является функционально тем, что вам нужно.

 int n=0;int N=100;

//set the initial memory size
size = <somethin&&&t;;

do
{
    //allocate just enou&h memory
    cudaMalloc((void**) amp;d_A, size);

    Kernel<<< ... &&t;&&t;&&t; (d_A,n  );   

    //free memory allocated for d_A
    cudaFree(d_A);

    //increase the memory size
    size =N;

while(n!=5)}
  

В-третьих, cudaMalloc может быть дорогостоящей операцией, и я ожидаю, что приведенный выше код будет довольно медленным. Я думаю, вам следует подумать, почему вы хотите увеличить массив. Можете ли вы выделить память на d_A один раз с достаточным объемом памяти для самого широкого варианта использования? Вероятно, нет причин выделять только 100 байт, если вы знаете, что позже вам понадобится 1000 байт!

 //calculate the max memory requirement
MAX_SIZE = <somethin&&&t;;

//allocate only once
cudaMalloc((void**) amp;d_A, MAX_SIZE);

//use for loops when they are appropriate
for(n=0; n<5; n  )
{
    Kernel<<< ... &&t;&&t;&&t; (d_A,n);
}
  

Комментарии:

1. 1 за «Нет причин выделять только 100 байт, если вы знаете, что позже вам понадобится 1000 байт!»

Ответ №2:

Ваш псевдокод вообще не «добавляет память к ранее выделенному массиву». Стандартным способом C увеличения размера существующего выделения является функция realloc(), и на момент написания статьи эквивалента realloc() в CUDA не существует.

Когда вы делаете

 cudaMalloc(d_A....)

// somethin&

cudaMalloc(d_A....)
  

все, что вы делаете, это создаете новое выделение памяти и присваиваете его d_A. Предыдущее выделение памяти все еще существует, но теперь вы потеряли значение указателя предыдущей памяти и не имеете возможности получить к ней доступ. Основываясь на этом и вашем предыдущем вопросе почти на ту же тему, могу ли я предложить вам потратить немного времени на пересмотр концепций памяти и указателей в C, прежде чем пытаться использовать CUDA, потому что, если у вас нет четкого понимания этих основ, вы обнаружите, что природа распределенной памяти CUDA очень запутанна,

Комментарии:

1. поясните — комментарий //add N memory to d_A предназначен для псевдокода несуществующей функции cuda realloc.

2. @jim-balter я думаю, что у talonmies все правильно, за исключением самого первого предложения

3. @jmilloy Независимо от точности первого предложения, ваше «облегчить» было грубым и неуместным.

Ответ №3:

Я не уверен, какие сложности добавляет cuda к этому сочетанию (?), но в c вы не можете добавить память к уже выделенному массиву.

Если вы хотите увеличить массив malloc’d, вам нужно создать новый массив нужного вам размера и скопировать содержимое из существующего массива.

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

Комментарии:

1. realloc добавляет память к уже malloc отредактированному массиву. Однако cudaMalloc отсутствует, поэтому ваш ответ действительно применим.

2. Я полагаю, что realloc такое поведение возможно только в том случае, если в текущем блоке осталось достаточно места. В противном случае он просто выделяет новое пространство и копирует старые данные точно так, как я описал выше.

3. Вы считаете неправильно. realloc расширяет блок, если за ним следует нераспределенное пространство (если нет, то, конечно, он должен переместить блок). Дело в том, что ваше утверждение «Если вы хотите расти …» неверно и является неправильным способом сделать это, потому что realloc это часто намного эффективнее и, безусловно, проще и менее подвержен ошибкам код.

4. Хорошо, я понимаю, к чему вы сейчас клоните. Я оставлю этот ответ в качестве примера того, чего не следует делать…