【发布时间】:2021-11-02 16:28:55
【问题描述】:
我直接在cuda内核中访问host mem,没有发现错误,这是为什么呢?
我试图通过documentation 变得更聪明。
分配页面锁定且可供设备访问的主机内存的 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);
}
【问题讨论】: