2013-05-14 75 views
1

如何为OpenCL中的所有线程声明一个全局设备变量? 我正在将一些代码从CUDA移植到OpenCL。在我的CUDA实现我有类似全局设备变量OpenCL

... 
... 

__device__ int d_var; 

... 
... 
void foo() { 
    int h_var = 0 
    cudaMemcpyToSymbol(d_var, h_var, sizeof(int)); 
    do{ 
     //launch kernel, inside kernel d_var is modified 
     cudaMemcpyFromSymbol(h_var, d_var, sizeof(int)); 
    }while(h_var != 0); 
} 

我一直在读通过OpenCL的例子代码,但无法弄清楚如何做到这一点。 任何建议将是伟大的!

回答

1

不幸的是,这不是直接进入港口。尽管我不完全确定你是否至少可以在OpenCL程序中定义和使用(读/写)这样的全局变量(但我不这么认为),但是肯定没有办法访问(读/写)这个变量来自主机。

你将不得不做的是把它作为一个额外的内核参数放到内核中。如果仅由主机写入并由内核读取,则普通的int变量就足够了(因此每个内核都有一个副本)。但是,在你的情况,因为它也被写入内核和读取从主机,它必须是一个__global指针,到适当的缓冲势必:

__kernel void func(..., __global int *d_var) { ... } 

然后你就可以读取和写入在主机上使用通常的缓冲区功能(当然,在内核中通过经典指针取消引用*d_var,但请记住,如果不是原子性的,则对此变量的并发写入具有未指定的结果)。

+0

对不起,我在我的代码中犯了一个错误。有一个主机** h_var **和一个设备** d_var **,然后我从device2host来回复制。我想我将不得不按照你的建议创建另一个缓冲区。我试着用'__kernel void foo(...,__constant int d_var)',但是我得到一个错误,是因为d_var不是指针吗? – BRabbit27 2013-05-14 17:12:09

+0

@ BRabbit27 *“是否因为d_var不是指针?” - 是的。我了解你的代码示例,答案仍然适用。你必须为你的'd_var'(仅仅是一个'int'或者一个更大的缓冲区的子缓冲区)创建一个缓冲区,并使用通常的缓冲区读/写从那里复制到'h_var',反之亦然操作。然后像往常一样将此缓冲区作为'* d_var'参数的内核参数传递。顺便说一下,如果你想在内核中写入'd_var',就像你在问题中写的那样,你需要'__global'而不是'__constant'。 – 2013-05-14 17:16:12

+0

哦,是的,我的错误,我会马上尝试。 – BRabbit27 2013-05-14 18:42:23

0

对于适合变量的小项目,将它们作为参数传递。

对于较大的常量项目,请使用OpenCL“常量”地址空间。它针对广播使用进行了优化。

在您的CUDA示例中,您将数据读回。在OpenCL中,您需要为此使用常规缓冲区对象,因为参数不会读回主机,并且常量内存是只读的。