integer,device ::a_d=3 是将a放在GPU,也就是device的DRAM上了对吗?也就是对应软件概念上的global memory对吗?
通过参数传递call subroutine_name <<<1,1>>>(a_d)
attributes(global) subroutine subroutine_name (a) ,在subroutine中可以对进行读取和赋值等操作,但是:
不通过参数传递, call subroutine_name <<<1,1>>>()
attributes(global) subroutine subroutine_name () ,
在subroutine中就访问不到a,读取不到赋值为3的a_d
请问 1 kernel函数如何才能访问global memory,一定要传参吗?我想想觉得既然已经定义到global menmory了,是全局变量,那这个参数对所有线程都应该是可见的吧。请指正我的想法。
2 在kernel中,也就是subroutine,中定义的变量,是局部变量,它是存储在什么memory中的?
感谢版主能回答我的问题~
翻译成cuda c大概是这样子,不知道准不准确。请您看一下
int main(void)
{
int a,b,c;
int dev_a,dev_b,dev_c;
HANDLE_ERROR(cudaMalloc((void)&dev_a,sizeof(int)));
HANDLE_ERROR(cudaMalloc((void*)&dev_b,sizeof(int)));
HANDLE_ERROR(cudaMalloc((void**)&dev_c,sizeof(int)));
a=1;
b=1;
HANDLE_ERROR(cudaMemcpy(dev_a,a,sizeof(int),cudaMemcpyHostToDevice));
HANDLE_ERROR(cudaMemcpy(dev_b,b,sizeof(int),cudaMemcpyHostToDevice));
add<<<1,1>>>(dev_a,dev_b,dev_c);
HANDLE_ERROR(cudaMemcpy(c,dev_c,sizeof(int),cudaMemcpyDeviceToHost));
printf(c);
return 0;
}
cudaFree(dev_c);
cudaFree(dev_a);
cudaFree(dev_b);
return 0;
}
global void add(int *a, int *b, int *c)
{
c = a + b;
}
请问:以上代码是通过传参的,就是add<<<1,1>>>(dev_a,dev_b,dev_c);圆括号中有参数,我想知道如果圆括号中没有参数,在kernel中直接对dev_a,dev_b,dev_c 进行操作为什么不行,比如直接写dev_c=dev_a+dev_b
LZ您好,根据您3#的代码,我大致说几点:
1:您的用法框架是正确的,您的kernel函数内部应该是值相加而不是指针自己相加,估计您笔误了。
2:如果只需要给kernel几个值的参数的话,无需这样用dev_a,dev_b的指针。直接把host上a,b变量作为函数参数即可,启动kernel的时候会复制a,b的值,作为参数,压给kernel函数的。
如果是要给kernel多个数据,如一个数组/线性缓冲区。那么推荐使用这样的传递指针的方法。
3:如果您一定要用device端的全局变量/全局数组,那么可以用__device__修饰的变量和数组定义。此时会通过特殊处理,使该变量/数组成为device端的全局可见的。但是,此时host端要使用cudaGetSymbolAddress()来获取其地址,或者使用cudaMemcpyToSymbol()函数来完成copy。总体而言,建议使用您当前使用的通过指针访问global memory上一段线性缓冲区/数组的用法。
大致如上,祝您编码顺利~