我是 OpenCL 新手,对这个限制感到非常困惑。例如,如果我想写一个LCG,我必须使状态字可以修改为rand()
and srand()
。在 ANSI C 中,我将使用以下方法来做到这一点:
/* ANSI C */
static unsigned long _holdrand = 1; /* Global! */
unsigned long rand(){
_holdrand = _holdrand * 214013L + 2531011L;
return (_holdrand >> 16) & 0x7FFF;
}
void srand( unsigned long seed ){
_holdrand = seed;
}
但 OpenCL 限制所有全局范围变量__constant
。我可以移动_holdrand
进入函数作用域,并从该函数返回它的指针。
/* OpenCL C */
uint* holdrand(){
__private static uint _holdrand = 1;
return &_holdrand;
}
uint rand(){
*holdrand() = *holdrand() * 214013L + 2531011L;
return (*holdrand() >> 16) & 0x7FFF;
}
void srand( uint seed ){
*holdrand() = seed;
}
它工作正常,我不知道这是否是一个好的解决方案。这个限制毫无意义,我只是通过添加更多奇怪的代码来避免它。
__private uint _holdrand = 1;
/* It should be the same thing... Why this is not allowed? */
由于返回静态指针方式的行为与 ANSI C 中的全局范围变量方法完全相同,因此我无法理解该限制的含义。有人可以解释为什么吗?我错过了什么吗?我应该做什么才能使_holdrand
在这个例子中可以在两个不同的函数中修改吗?
简而言之 - OpenCL 程序生命周期和内存布局与 C 程序不同。在 OpenCL 中,没有堆栈、堆等。常量内存(通常)非常快且片上内存量很少,IO 操作与寄存器操作相比具有相同的性能顺序。因此,它对工作项的写入操作可能有限制。
每个 NDRange(通常)中都有数千个工作项 (WI)。想象一下,如果 512 个线程正在读取/写入同一变量,您可以实现什么性能。这就是为什么你有 4 个地址空间:
-
__private
对于每一个WI
-
__local
对于工作组内的所有 WI
-
__global
适用于 NDRange 内的所有 WI
-
__constant
对于全局只读变量
If your rand()
& srand()
函数是 WI 特定的,您应该使用私有内存。另一种方法是在全局地址空间中包含所需的变量。但在这种情况下要非常小心竞争条件。
OpenCL 可以在各种各样的设备上运行,这就是为什么某些限制看起来太严格的原因。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)