Trong CUDA C Best Practices Guide Phiên bản 5.0, Mục 6.1.2, nó được viết rằng:Ảnh hưởng của việc sử dụng bộ nhớ trang có thể cho bản sao bộ nhớ không đồng bộ?
Ngược lại với cudaMemcpy(), phiên bản asynchronous transfer đòi hỏi bộ nhớ lưu trữ gắn (xem Memory Pinned), và nó chứa một đối số bổ sung , một ID luồng.
Có nghĩa là chức năng cudaMemcpyAsync
sẽ bị lỗi nếu tôi sử dụng bộ nhớ đơn giản.
Nhưng đây không phải là những gì đã xảy ra.
Chỉ cần cho mục đích thử nghiệm, tôi đã thử chương trình sau đây:
Kernel:
__global__ void kernel_increment(float* src, float* dst, int n)
{
int tid = blockIdx.x * blockDim.x + threadIdx.x;
if(tid<n)
dst[tid] = src[tid] + 1.0f;
}
chính:
int main()
{
float *hPtr1, *hPtr2, *dPtr1, *dPtr2;
const int n = 1000;
size_t bytes = n * sizeof(float);
cudaStream_t str1, str2;
hPtr1 = new float[n];
hPtr2 = new float[n];
for(int i=0; i<n; i++)
hPtr1[i] = static_cast<float>(i);
cudaMalloc<float>(&dPtr1,bytes);
cudaMalloc<float>(&dPtr2,bytes);
dim3 block(16);
dim3 grid((n + block.x - 1)/block.x);
cudaStreamCreate(&str1);
cudaStreamCreate(&str2);
cudaMemcpyAsync(dPtr1,hPtr1,bytes,cudaMemcpyHostToDevice,str1);
kernel_increment<<<grid,block,0,str2>>>(dPtr1,dPtr2,n);
cudaMemcpyAsync(hPtr2,dPtr2,bytes,cudaMemcpyDeviceToHost,str1);
printf("Status: %s\n",cudaGetErrorString(cudaGetLastError()));
cudaDeviceSynchronize();
printf("Status: %s\n",cudaGetErrorString(cudaGetLastError()));
cudaStreamDestroy(str1);
cudaStreamDestroy(str2);
cudaFree(dPtr1);
cudaFree(dPtr2);
for(int i=0; i<n; i++)
std::cout<<hPtr2[i]<<std::endl;
delete[] hPtr1;
delete[] hPtr2;
return 0;
}
Chương trình đưa ra chính xác. Mảng tăng lên thành công.
Cách thực hiện cudaMemcpyAsync
mà không có bộ nhớ bị khóa trang? Tôi có thiếu gì đó ở đây không?
@NolwennLeGuen ... thực sự nó đã là một yêu cầu ngay từ đầu. Tôi đã đọc điều này trong các hướng dẫn CUDA trước đây. – sgarizvi
@NolwennLeGuen: Đây là hành vi tuyệt đối được mong đợi, không có "công cụ hộp đen" có liên quan. Nếu bạn không có bất kỳ điều gì có tính xây dựng để thêm vào cuộc thảo luận, vui lòng không tham gia vào cuộc thảo luận đó. – talonmies
Tài liệu cho các trạng thái hàm _Điều này thể hiện hành vi không đồng bộ cho hầu hết các trường hợp sử dụng._.Nếu bộ nhớ có thể thu thập được sử dụng thì trình điều khiển phải sao chép bộ nhớ vào bộ đệm không thể phân trang. Nếu kích thước truyền lớn hơn bộ đệm không thể đánh dấu của trình điều khiển thì trình điều khiển chờ bộ đệm không thể thu thập được để hoàn thành phần còn lại của quá trình chuyển. –