cuda - cudaMemset 是否应该在从 cudaHostRegister 映射的设备指针上工作
问题描述
我从我的一位同事那里看到了示例代码,其中 cudaMemset 在 V100 上运行时似乎无法正常工作。
#include <iostream>
#include <stdio.h>
#define CUDACHECK(cmd) \
{\
cudaError_t error = cmd;\
if (error != cudaSuccess) { \
fprintf(stderr, "info: '%s'(%d) at %s:%d\n", cudaGetErrorString(error), error,__FILE__, __LINE__);\
}\
}
__global__ void setValue(int value, int* A_d) {
int tx = threadIdx.x + blockIdx.x * blockDim.x;
if(tx == 0){
A_d[tx] = A_d[tx] + value;
}
}
__global__ void printValue(int* A_d) {
int tx = threadIdx.x + blockIdx.x * blockDim.x;
if(tx == 0){
printf("A_d: %d\n", A_d[tx]);
}
}
int main(int argc, char* argv[ ]){
int *A_h, *A_d;
int size = sizeof(int);
A_h = (int*)malloc(size);
A_h[0] = 1;
CUDACHECK(cudaSetDevice(0));
CUDACHECK(cudaHostRegister(A_h, size, 0));
CUDACHECK(cudaHostGetDevicePointer((void**)&A_d, A_h, 0));
setValue<<<64,1,0,0>>>(5, A_d);
cudaDeviceSynchronize();
printf("A_h: %d\n", A_h[0]);
A_h[0] = 100;
printf("A_h: %d\n",A_h[0]);
printValue<<<64,1,0,0>>>(A_d);
cudaDeviceSynchronize();
CUDACHECK (cudaMemset(A_d, 1, size) );
printf("A_h: %d\n",A_h[0]);
printValue<<<64,1,0,0>>>(A_d);
cudaDeviceSynchronize();
cudaHostUnregister(A_h);
free(A_h);
}
编译并运行此示例时,输出如下所示。
/usr/local/cuda-11.0/bin/nvcc memsettest.cu -o test
./test
A_h: 6
A_h: 100
A_d: 100
A_h: 16843009
A_d: 16843009
我们期望 A_h 和 A_d 使用 cudaMemset 设置为 1。但正如所见,它被设置为一些巨大的价值。因此,cudaMemset 是否有望在 cudaHostGetDevicePointer 返回的设备指针 A_d 上工作。这个 A_d 是否预计仅在内核中使用。我们还看到 cudaMemcpy DtoH 或 HtoD 似乎在同一个设备指针 A_d 上工作。有人可以帮助我们正确的行为。
解决方案
我们期望 A_h 和 A_d 使用 cudaMemset 设置为 1。
你对如何cudaMemset
工作感到困惑。从概念上讲,它与 C 标准库中的非常相似memset
。您应该尝试使用相同的测试用例memset
,看看它做了什么。
无论如何,cudaMemset
需要一个指针、一个字节值和一个以字节为单位的大小来设置,就像memset
.
所以你的cudaMemset
命令:
CUDACHECK (cudaMemset(A_d, 1, size) );
将每个字节设置为 1。因为size
是 4,这意味着您设置A_d[0]
为0x01010101
(十六进制)。如果将该值插入 Windows 程序员计算器,则该值是十进制的 16843009。所以一切都按预期工作,在这里,从我所看到的。
同样,我很确定memset
对于相同的测试用例/用法,您会看到相同的行为。
推荐阅读
- php - 如何在 S3 的树枝文件中使用相对路径?
- rhel7 - Podman build 命令无法拉取镜像
- node.js - puppeteer 表单填写日期字段未填写年份
- google-sheets - 具有特定格式内容的表格上的过滤功能 google-sheets
- postgresql - 添加可为空的列是否存在表重写的情况?
- java - 如何在不覆盖当前内容的情况下写入文件,同时限制 Java 中的文件大小
- android - Flutter:没有虚拟方法 getLongVersionCode(),Sdk 29
- javascript - 如何在 SSR React 应用程序中以编程方式获取我的 Google 优化实验 ID?
- javascript - 创建 ms 团队应用程序中的 javascript 实现问题
- javascript - 没有得到第三个条件