Dành một chút thời gian tập trung vào tài liệu phong phú do NVIDIA cung cấp.
Từ Programming Guide:
float* devPtr;
cudaMalloc((void**)&devPtr, 256 * sizeof(*devPtr));
cudaMemset(devPtr, 0, 256 * sizeof(*devPtr));
Đó là một ví dụ đơn giản về cách cấp phát bộ nhớ. Bây giờ, trong hạt nhân của bạn, bạn nên chấp nhận một con trỏ đến một phao như vậy:
__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;
}
Vì vậy, bây giờ bạn có thể gọi họ như vậy:
float* devPtr;
cudaMalloc((void**)&devPtr, 256 * sizeof(*devPtr));
cudaMemset(devPtr, 0, 256 * sizeof(*devPtr));
kernel1<<<1,128>>>(devPtr);
kernel2<<<1,128>>>(devPtr);
Theo dữ liệu này được sử dụng trong nhiều chức năng, tôi muốn nó là toàn cầu.
Có một vài lý do chính đáng để sử dụng hình cầu. Điều này chắc chắn không phải là một. Tôi sẽ để nó như một bài tập để mở rộng ví dụ này để bao gồm việc chuyển "devPtr" sang phạm vi toàn cầu.
EDIT:
Ok, vấn đề cơ bản là thế này: hạt nhân của mình chỉ có thể truy cập bộ nhớ điện thoại và các con trỏ toàn cầu phạm vi duy nhất mà họ có thể sử dụng là những GPU. Khi gọi một hạt nhân từ CPU của bạn, đằng sau hậu trường những gì xảy ra là các con trỏ và nguyên thủy được sao chép vào thanh ghi GPU và/hoặc bộ nhớ chia sẻ trước khi hạt nhân được thực thi.
Vì vậy, gần nhất tôi có thể đề xuất là: sử dụng cudaMemcpyToSymbol() để đạt được mục tiêu của bạn. Nhưng, ở chế độ nền, hãy xem xét một cách tiếp cận khác có thể là Điều Đúng.
#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;
}
Đừng quên '--host-compilation = C++' cho ví dụ này.
Hãy xem sử dụng bộ nhớ dùng chung, toàn cầu là lớp bộ nhớ thiết bị chậm nhất. – SpaceghostAli
Tại sao bạn muốn sử dụng hình cầu thay vì truyền con trỏ thiết bị làm đối số cho hạt nhân? Làm như vậy chỉ cung cấp cho bạn tất cả các hạn chế tương tự như sử dụng bộ nhớ toàn cầu trong mã CPU, với ít lợi thế. –