用户
 找回密码
 立即注册
xlwhlb 该用户已被删除
发表于 2013-11-16 10:15:32
2907913
代码如下:
  1. #define Nx 24
  2. #define Ny 24
  3. int main()
  4. {        
  5.         float *data_GPU,*test;
  6.         cudaMalloc((void**)&data_GPU,sizeof(float)*Nx*Ny);cudaMemset(data_GPU,3.0,Nx*Ny*sizeof(float));
  7.         cudaMalloc((void**)&test,sizeof(float)*Nx*Ny);cudaMemset(test,0.0,Nx*Ny*sizeof(float));
  8.         dim3 threadsPerblock=(8,8);
  9.         dim3 blockspergrid=(3,3);
  10.         //mykernel<<<blockspergrid,threadsPerblock>>>(data_GPU,test);
  11.         cudaDeviceSynchronize();
  12.         printf("cudaGetLastError=%s\n",cudaGetErrorString(cudaGetLastError()));

  13.         float *CPU_data;
  14.         cudaMallocHost((void**)&CPU_data,sizeof(float)*Nx*Ny);
  15.         cudaMemcpy(CPU_data,data_GPU,sizeof(float)*Nx*Ny,cudaMemcpyDeviceToHost);

  16.         for(int iy=0;iy<Ny;iy++){
  17.                 for(int ix=0;ix<Nx;ix++){
  18.                         printf("CPU_DATA=%f\n",CPU_data[iy*Nx+ix]);
  19.                 }
  20.         }

  21.         cudaFreeHost(CPU_data);
  22.         cudaFree(data_GPU);
  23.         cudaFree(test);

  24.         return 0;
  25. }
复制代码
kerne函数已经被屏蔽,本意是想用memset对显存上数据data_GPU初始化为3.0,但是发现好像没有成功呢?因为拷贝到CPU上发现都是0.000。
多谢斑竹
使用道具 举报 回复
发表于 2013-11-16 10:26:46
楼主您好,3.0f不可以用cudaMemset设置。

3.0f的16进制表示是:0x40400000
字节表示是:00 00 40 40 (x86 / GPU)

只有4个字节完全一样的float才能用cudaMemset清零的(例如0.0f)

建议的解决方案:
请您手写一个单独的kernel用来设置初始值为3.0f,在启动您的需要使用初始化过的缓冲区前调用此kernel,然后再调用您需要的kernel。

感谢您的周末来访。
使用道具 举报 回复 支持 反对
发表于 2013-11-16 10:30:56
横扫千军 发表于 2013-11-16 10:26
楼主您好,3.0f不可以用cudaMemset设置。

3.0f的16进制表示是:0x40400000

哦哦 原来是这样啊 多谢横扫版主
使用道具 举报 回复 支持 反对
发表于 2013-11-16 10:40:20
xlwhlb 发表于 2013-11-16 10:30
哦哦 原来是这样啊 多谢横扫版主

您客气了,服务您是我们的荣幸。

感谢您的周末来访。
使用道具 举报 回复 支持 反对
发表于 2013-11-16 10:47:16
横扫千军 发表于 2013-11-16 10:40
您客气了,服务您是我们的荣幸。

感谢您的周末来访。
  1. __global__ void Initialization(float *aa)
  2. {
  3.         int ix=blockDim.x*blockIdx.x+threadIdx.x;
  4.         int iy=blockDim.y*blockIdx.y+threadIdx.y;
  5.         int in_idx=iy*Nx+ix;
  6.         aa[in_idx]=3.0;
  7.         //__syncthreads();
  8. }
复制代码
横扫斑竹,加入这段代码有没有设备上的数据初始化为3.0的功能呢?
为什么只有数据的前24个元素是3.0,其余还是0呢
使用道具 举报 回复 支持 反对
发表于 2013-11-16 10:53:16
xlwhlb 发表于 2013-11-16 10:47
横扫斑竹,加入这段代码有没有设备上的数据初始化为3.0的功能呢?
为什么只有数据的前24个元素是3.0,其余 ...

楼主您好,

您的kernel将对从0到in_idx最大值的所有aa[in_idx]元素进行设置为3.0f的操作。

这个kernel是否正确执行只取决与您的in_idx能达到的范围,也就是您的启动形状配置。

如果您真实的给出了您的代码(如上文),则您的唯一问题在与您的线程形状覆盖,请您重新设置您的启动形状配置。这是唯一您可能出错的方面。

请您立刻按照上文修改。
感谢您的周末来访。
使用道具 举报 回复 支持 反对
发表于 2013-11-16 11:14:18
玫瑰幻想 发表于 2013-11-16 10:53
楼主您好,

您的kernel将对从0到in_idx最大值的所有aa元素进行设置为3.0f的操作。

感谢斑竹,已找到错误
使用道具 举报 回复 支持 反对
发表于 2013-11-17 13:00:00

RE: 关于CudaMemset()函数

本帖最后由 yuanwcj 于 2013-11-17 13:01 编辑
横扫千军 发表于 2013-11-16 10:26
楼主您好,3.0f不可以用cudaMemset设置。

3.0f的16进制表示是:0x40400000


请问横扫版主,"只有4个字节完全一样的float才能用cudaMemset清零的(例如0.0f)",这句话是什么意思...
4个字节完全一样才能使用cudaMemset?这个为什么是这样的,或者是由哪方面的因素决定了,必须要求4字节一样的..谢谢
使用道具 举报 回复 支持 反对
发表于 2013-11-17 13:14:08
yuanwcj 发表于 2013-11-17 13:00
请问横扫版主,"只有4个字节完全一样的float才能用cudaMemset清零的(例如0.0f)",这句话是什么意思...
4个 ...

yuanwcj您好:

因为cudaMemset()在进行memset的时候是按照BYTE写入的,所有的字节都写成一样的内容,而且跟这段缓冲区原本存放的类型是float还是int还是其他类型无关。

所以,严格说,只有4个字节完全一样的float才能使用cudaMemset()进行初始化,而这种float一般只有0.0f比较常见,其他情况都是专门凑出来的,换句话说,cudaMemset()一般只拿来清零。

如果您需要统一初始化为其他特定的数值,请启动一个kernel对缓冲区赋值即可。

大致如此,祝您好运~
使用道具 举报 回复 支持 反对
发表于 2013-11-17 15:16:38
谢谢ice版主,
在C/C++中,Memset指令赋值时好像是没这个限制的;
包括从C/C++中引申出来的其他几个cudaMem*指令,同C/C++中的指令也基本上差不多,怎么到了cudaMemset指令,就有区别了呢,这个是由什么原因引起的,还是说与gpu的结构或处理方式相关,谢谢?
使用道具 举报 回复 支持 反对
12下一页
发新帖
您需要登录后才可以回帖 登录 | 立即注册