Давай пока оставим CUDA. Давайте просто сделаем функцию, которая записывает данные в предоставленный пользователем массив. Пользователь передает массив через указатель:
void fill_me_up(int * dst)
{
// We sure hope that `dst` points to a large enough area of memory!
dst[0] = 28;
dst[1] = 75;
}
Теперь то, что вы делаете с локальной переменной, не имеет смысла, потому что вы хотите использовать адрес локальной переменной, который становится недействительным после выхода из области действия функции. Следующее лучшее, что вы можете сделать, это memcpy()
, или какой-то эквивалентный алгоритм C ++:
void fill_me_up_again(int * dst)
{
int temp[] = { 28, 75 };
memcpy((void *)dst, (const void *)temp, sizeof(temp));
}
Хорошо, теперь вызовите эту функцию: сначала мы должны предоставить целевую память, а затем передать указатель:
int main()
{
int my_memory[2]; // here's our memory -- automatic local storage
fill_me_up(my_memory); // OK, array decays to pointer-to-beginning
fill_me_up(&my_memory[0]); // A bit more explicit
int * your_memory = malloc(sizeof(int) * 2); // more memory, this time dynamic
fill_me_up_again(your_memory);
/* ... */
free(your_memory);
}
(В C ++ вы, вероятно, могли бы использовать new int[2]
и delete your_memory
вместо этого, но, используя C malloc()
, мы надеемся, что соединение с CUDA станет ясным.)
Когда вы перемещаете fill_me_up
на устройство CUDA, вы должны присвоить ему указатель устройства, а не указатель хоста, поэтому вы должны сначала установить его, а затем скопировать результаты обратно, но это примерно единственное изменение.