我在cuda内核中直接访问主机内存,没有发现错误,为什么会这样?
我试图从文档中获取更多信息。
分配大小为size的主机内存,该内存是页面锁定的,并且可被设备访问。驱动程序跟踪使用此函数分配的虚拟内存范围,并自动加速对诸如cudaMemcpy*()之类的函数的调用。由于设备可以直接访问内存,因此与使用malloc()等函数获得的可分页内存相比,它可以具有更高的带宽。
为什么许多cuda程序在cudaMallocHost之后添加cudaMemcpy?
我试图从文档中获取更多信息。
分配大小为size的主机内存,该内存是页面锁定的,并且可被设备访问。驱动程序跟踪使用此函数分配的虚拟内存范围,并自动加速对诸如cudaMemcpy*()之类的函数的调用。由于设备可以直接访问内存,因此与使用malloc()等函数获得的可分页内存相比,它可以具有更高的带宽。
为什么许多cuda程序在cudaMallocHost之后添加cudaMemcpy?
#include <stdio.h>
#include <assert.h>
#define N 64
// cuda kernel access host mem a/b
__global__ void gpu(int *a, int *b, int *c_gpu) {
int r = blockDim.x * blockIdx.x + threadIdx.x;
int c = blockDim.y * blockIdx.y + threadIdx.y;
if (r < N && c < N) {
c_gpu[r * N + c] = a[r * N + c] + b[r * N + c];
}
}
// cpu function
void cpu(int *a, int *b, int *c_cpu) {
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
c_cpu[r * N + c] = a[r * N + c] + b[r * N + c];
}
}
}
int main() {
int *a, *b, *c_cpu, *c_gpu, *c_gpu_cpu;
size_t size = N * N * sizeof(int);
cudaMallocHost(&a, size);
cudaMallocHost(&b, size);
cudaMallocHost(&c_cpu, size);
cudaMallocHost(&c_gpu_cpu, size);
cudaMalloc(&c_gpu, size);
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
a[r * N + c] = r;
b[r * N + c] = c;
c_gpu_cpu[r * N + c] = 0;
c_cpu[r * N + c] = 0;
}
}
cpu(a, b, c_cpu);
dim3 threads(16, 16, 1);
dim3 blocks((N + threads.x - 1) / threads.x, (N + threads.y - 1) / threads.y, 1);
gpu<<<blocks, threads>>>(a, b, c_gpu); // access cpu host mem
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) {
printf("Error: %s\n", cudaGetErrorString(err));
}
cudaDeviceSynchronize();
cudaFreeHost(a);
cudaFreeHost(b);
cudaFreeHost(c_cpu);
cudaFreeHost(c_gpu_cpu);
cudaFree(c_gpu);
}