Глобальная переменная в CUDA - PullRequest
7 голосов
/ 06 июня 2011

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

Как создать массивы внутри функции CUDA, например

__global__ void test()
{
  int *a = new int[10];
}

или Как создать глобальный массив и получить к нему доступ из этой функции.например

__device__ int *a;
__global__ void test()
{
  a[0] = 2;
}

Или как я могу использовать, как показано ниже ..

__global__ void ProcessData(int img)
{
   int *neighborhood = new int[8]; 
   getNeighbourhood(img, neighbourhood);
}

Тем не менее у меня есть некоторые проблемы с этим.Я обнаружил, что сравнение с

__device__

, если я определю

"__device__ __constant__" (read only)

, улучшит доступ к памяти.Но моя проблема в том, что у меня есть массив в памяти хоста, скажем

 float *arr = new float[sizeOfTheArray]; 

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

1 Ответ

9 голосов
/ 06 июня 2011

Оператор C ++ new поддерживается в вычислительных возможностях 2.0 и 2.1 (т. Е. Fermi) с CUDA 4.0, поэтому вы можете использовать new для выделения глобальной памяти для символа устройства, хотя ни один из ваших первых двух фрагментов кода как это будет сделано на практике.

На старом оборудовании и / или с предыдущими наборами инструментов CUDA 4.0 стандартный подход заключается в использовании API cudaMemcpyToSymbol в коде хоста:

__device__ float *a;

int main()
{
    const size_t sz = 10 * sizeof(float);

    float *ah;
    cudaMalloc((void **)&ah, sz);
    cudaMemcpyToSymbol("a", &ah, sizeof(float *), size_t(0),cudaMemcpyHostToDevice);
}

, который копирует динамически назначенный указатель устройства на символ, который можно использовать непосредственно в коде устройства.


РЕДАКТИРОВАТЬ: Ответ на этот вопрос немного походит на удар по движущейся цели. Для случая постоянной памяти, который вам сейчас интересен, приведем полный рабочий пример:

#include <cstdio>

#define nn (10)

__constant__ float a[nn];

__global__ void kernel(float *out)
{
    if (threadIdx.x < nn)
        out[threadIdx.x] = a[threadIdx.x];

}

int main()
{
    const size_t sz = size_t(nn) * sizeof(float);
    const float avals[nn]={ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10. };
    float ah[nn];

    cudaMemcpyToSymbol("a", &avals[0], sz, size_t(0),cudaMemcpyHostToDevice);

    float *ad;
    cudaMalloc((void **)&ad, sz);

    kernel<<<dim3(1),dim3(16)>>>(ad);

    cudaMemcpy(&ah[0],ad,sz,cudaMemcpyDeviceToHost);

    for(int i=0; i<nn; i++) {
        printf("%d %f\n", i, ah[i]);
    }
}

Показывает копирование данных в постоянный символ памяти и использование этих данных внутри ядра.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...