Потратьте некоторое время, сосредотачиваясь на обильной документации, предлагаемой NVIDIA.
Из Руководства по программированию:
float* devPtr;
cudaMalloc((void**)&devPtr, 256 * sizeof(*devPtr));
cudaMemset(devPtr, 0, 256 * sizeof(*devPtr));
Это простой пример того, как выделить память. Теперь в ваших ядрах вы должны принять указатель на число с плавающей точкой, например:
__global__
void kernel1(float *some_neat_data)
{
some_neat_data[threadIdx.x]++;
}
__global__
void kernel2(float *potentially_that_same_neat_data)
{
potentially_that_same_neat_data[threadIdx.x] *= 0.3f;
}
Так что теперь вы можете вызывать их так:
float* devPtr;
cudaMalloc((void**)&devPtr, 256 * sizeof(*devPtr));
cudaMemset(devPtr, 0, 256 * sizeof(*devPtr));
kernel1<<<1,128>>>(devPtr);
kernel2<<<1,128>>>(devPtr);
Поскольку эти данные используются в многочисленных
функции, я хотел бы, чтобы это было
глобальный характер.
Есть несколько веских причин для использования глобалов. Это определенно не один. Я оставлю это в качестве упражнения, чтобы расширить этот пример, чтобы включить перемещение devPtr в глобальную область.
EDIT:
Хорошо, фундаментальная проблема заключается в следующем: ваши ядра могут получать доступ только к памяти устройства, и единственные указатели глобальной области видимости, которые они могут использовать, - это графические процессоры. При вызове ядра из вашего ЦП, за кулисами происходит то, что указатели и примитивы копируются в регистры GPU и / или разделяемую память до того, как ядро будет выполнено.
Итак, самое близкое, что я могу предложить, это использовать cudaMemcpyToSymbol () для достижения ваших целей. Но, на заднем плане, подумайте, что другой подход может быть правильным.
#include <algorithm>
__constant__ float devPtr[1024];
__global__
void kernel1(float *some_neat_data)
{
some_neat_data[threadIdx.x] = devPtr[0] * devPtr[1];
}
__global__
void kernel2(float *potentially_that_same_neat_data)
{
potentially_that_same_neat_data[threadIdx.x] *= devPtr[2];
}
int main(int argc, char *argv[])
{
float some_data[256];
for (int i = 0; i < sizeof(some_data) / sizeof(some_data[0]); i++)
{
some_data[i] = i * 2;
}
cudaMemcpyToSymbol(devPtr, some_data, std::min(sizeof(some_data), sizeof(devPtr) ));
float* otherDevPtr;
cudaMalloc((void**)&otherDevPtr, 256 * sizeof(*otherDevPtr));
cudaMemset(otherDevPtr, 0, 256 * sizeof(*otherDevPtr));
kernel1<<<1,128>>>(otherDevPtr);
kernel2<<<1,128>>>(otherDevPtr);
return 0;
}
Не забудьте для этого примера '--host-compilation = c ++'.