cudaMemset是否应在从cudaHostRegister

问题描述

我从一位同事那里碰到了示例代码,当在V100上运行时,cudamemset似乎无法正常工作。

#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>>>(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,0>>>(A_d);
        cudaDeviceSynchronize();
        CUDACHECK (cudamemset(A_d,size) );
        printf("A_h: %d\n",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

我们希望通过cudamemset将A_h和A_d设置为1。但是,正如所看到的那样,它具有巨大的价值。 因此,预计cudamemset可在cudaHostGetDevicePointer返回的设备指针A_d上工作。 该A_d是否仅在内核中使用? 我们还看到cudamemcpy DtoH或HtoD似乎在同一设备指针A_d上工作。 有人可以帮助我们采取正确的行为。

解决方法

我们希望通过cudaMemset将A_h和A_d设置为1。

您对cudaMemset的工作方式感到困惑。从概念上讲,它与C标准库中的memset非常相似。您应该使用memset尝试相同的测试用例,然后看看它能做什么。

无论如何,cudaMemset需要一个指针,一个字节值和一个以字节为单位的大小来设置,就像memset。>

因此,您的cudaMemset命令:

    CUDACHECK (cudaMemset(A_d,1,size) );

每个字节设置为1。由于size为4,这意味着您正在将A_d[0]设置为0x01010101(以十六进制表示)。如果将该值插入Windows程序员计算器,则该值为十进制16843009。因此,从我所看到的一切来看,一切都按预期进行。

同样,我很确定您会在相同的测试用例/用法下看到与memset相同的行为。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...