float * addr = NULL; 或 float *addr = new float[3000];
cudaMalloc(&addr,sizeof(float)*3000);
由于某次只想使用其中的一个值 因此直接写addr[0]=0.5;
接下来Initial<<<nBlocks,nThreadsPerBlock>>>(addr) 出错 could not find source
即使用for (int k=0;k<3000;k++) addr[0] =0.5;也出错 could not find source :o
补充一下 打算直接addr[i]这个赋值了 不打算起多个GPU上线程去做,因为一个任务,行不行
cuda编程刚刚接触,不知道问题描述清楚没,请高手指教下,谢谢
“float * addr = NULL; 或 float *addr = new float[3000];
cudaMalloc(&addr,sizeof(float)*3000);”
第一行是分配主机端的内存,第二行是分配设备端的内存。
两个一起用当然回出错。如果你想用“Initial<<<nBlocks,nThreadsPerBlock>>>(addr) ”,请只要第二行。
如果循环赋值,请只要第一行。
这是我的一点浅见。
第二行调用cudaMalloc以后,原来在CPU内存空间给addr分配的空间就再也无法访问到了,这会造成内存泄露。同时,addr保存了指向GPU内存空间的地址,而CPU是无法直接访问到的,所以你加一个赋值addr[0]=0.5肯定是无法找到地址的(这个地址在GPU内存上,CPU是看不到的)。要操作GPU内存,只能用cudaMem…之类的函数以及使用kernel!
LZ您好,您的问题实际上是两个问题:
1:如何申请空间
2:如何对已经申请的空间赋值。
先说1:
您需要先确定您申请的空间是在host端(CPU端)还是device端(GPU端)。
如果是host端,那么使用常规的C/C++里面的函数,比如malloc或者您的float *addr = new float[3000];均可。这样申请了host端内存里面的空间,并且由指针addr指向该空间。
如果您要申请的是device端的空间,那么一般的做法是
先float * addr = NULL;定义一个指针
然后cudaMalloc(&addr,sizeof(float)*3000);申请GPU的显存空间,并由addr指向。
此时,指针addr自身是保存在CPU端的内存里面,但是addr指向的地址却是GPU端显存空间的地址。可以将addr指针作为参数传给kernel函数使用。
---------------------------问题1和问题2的分割线--------------------------------
下面说问题2
如果您在问题1中申请的是CPU端的空间,那么您可以按照任何传统的C/C++的赋值方法对您申请的空间中的变量赋值,这个不再赘述。
如果您在问题1中申请的是GPU端的空间,那么一般有两种做法:
方法a: 您可以在host端申请一个同样大小的数组,比如叫addr_host,然后用CPU端赋值的方法对addr_host初始化和赋值,然后使用cudaMemcpy()函数,将addr_host的内容赋值给GPU端的addr数组即可。(需要说明的是,如果只需要对addr的一部分连续的空间赋值,那么host端的addr_host数组大小可以小于addr,哪怕是一个变量也可以。然后用cudaMemcpy()复制过去)
方法b:如果您的addr数组里面的值可以就地生成(而不是host端从某些输入来源比如说数据文件得到的),那您也可以写一个kernel来就地生成要给addr的值,并直接写入。
此外,如果您需要对addr进行清零的初始化的话,可以使用cudaMemset()函数。
您的问题大致回复如上,供您参考~
祝您编码愉快~