system
2013 年11 月 16 日 02:15
1
代码如下:
#define Nx 24
#define Ny 24
int main()
{
float *data_GPU,*test;
cudaMalloc((void**)&data_GPU,sizeof(float)*Nx*Ny);cudaMemset(data_GPU,3.0,Nx*Ny*sizeof(float));
cudaMalloc((void**)&test,sizeof(float)*Nx*Ny);cudaMemset(test,0.0,Nx*Ny*sizeof(float));
dim3 threadsPerblock=(8,8);
dim3 blockspergrid=(3,3);
//mykernel<<<blockspergrid,threadsPerblock>>>(data_GPU,test);
cudaDeviceSynchronize();
printf("cudaGetLastError=%s\n",cudaGetErrorString(cudaGetLastError()));
float *CPU_data;
cudaMallocHost((void**)&CPU_data,sizeof(float)*Nx*Ny);
cudaMemcpy(CPU_data,data_GPU,sizeof(float)*Nx*Ny,cudaMemcpyDeviceToHost);
for(int iy=0;iy<Ny;iy++){
for(int ix=0;ix<Nx;ix++){
printf("CPU_DATA=%f\n",CPU_data[iy*Nx+ix]);
}
}
cudaFreeHost(CPU_data);
cudaFree(data_GPU);
cudaFree(test);
return 0;
}
kerne函数已经被屏蔽,本意是想用memset对显存上数据data_GPU初始化为3.0,但是发现好像没有成功呢?因为拷贝到CPU上发现都是0.000。
多谢斑竹
system
2013 年11 月 16 日 02:26
2
楼主您好,3.0f不可以用cudaMemset设置。
3.0f的16进制表示是:0x40400000
字节表示是:00 00 40 40 (x86 / GPU)
只有4个字节完全一样的float才能用cudaMemset清零的(例如0.0f)
建议的解决方案:
请您手写一个单独的kernel用来设置初始值为3.0f,在启动您的需要使用初始化过的缓冲区前调用此kernel,然后再调用您需要的kernel。
感谢您的周末来访。
system
2013 年11 月 16 日 02:47
5
您客气了,服务您是我们的荣幸。
感谢您的周末来访。
__global__ void Initialization(float *aa)
{
int ix=blockDim.x*blockIdx.x+threadIdx.x;
int iy=blockDim.y*blockIdx.y+threadIdx.y;
int in_idx=iy*Nx+ix;
aa[in_idx]=3.0;
//__syncthreads();
}
横扫斑竹,加入这段代码有没有设备上的数据初始化为3.0的功能呢?
为什么只有数据的前24个元素是3.0,其余还是0呢
system
2013 年11 月 16 日 02:53
6
楼主您好,
您的kernel将对从0到in_idx最大值的所有aa[in_idx]元素进行设置为3.0f的操作。
这个kernel是否正确执行只取决与您的in_idx能达到的范围,也就是您的启动形状配置。
如果您真实的给出了您的代码(如上文),则您的唯一问题在与您的线程形状覆盖,请您重新设置您的启动形状配置。这是唯一您可能出错的方面。
请您立刻按照上文修改。
感谢您的周末来访。
system
2013 年11 月 17 日 05:00
8
[
请问横扫版主,“只有4个字节完全一样的float才能用cudaMemset清零的(例如0.0f)”,这句话是什么意思…
4个字节完全一样才能使用cudaMemset?这个为什么是这样的,或者是由哪方面的因素决定了,必须要求4字节一样的…谢谢
system
2013 年11 月 17 日 05:14
9
yuanwcj您好:
因为cudaMemset()在进行memset的时候是按照BYTE写入的,所有的字节都写成一样的内容,而且跟这段缓冲区原本存放的类型是float还是int还是其他类型无关。
所以,严格说,只有4个字节完全一样的float才能使用cudaMemset()进行初始化,而这种float一般只有0.0f比较常见,其他情况都是专门凑出来的,换句话说,cudaMemset()一般只拿来清零。
如果您需要统一初始化为其他特定的数值,请启动一个kernel对缓冲区赋值即可。
大致如此,祝您好运~
system
2013 年11 月 17 日 07:16
10
谢谢ice版主,
在C/C++中,Memset指令赋值时好像是没这个限制的;
包括从C/C++中引申出来的其他几个cudaMem*指令,同C/C++中的指令也基本上差不多,怎么到了cudaMemset指令,就有区别了呢,这个是由什么原因引起的,还是说与gpu的结构或处理方式相关,谢谢?
system
2013 年11 月 17 日 14:40
11
yuanwcj您好:
您确定C语言中string.h提供的memset()不是按每个字节操作的么?
欢迎莅临cudazone,祝您好运~
system
2013 年11 月 18 日 01:16
12
谢谢ice版主,刚查了下资料,现在才知道以前对memset函数一直有一个误解