Parallel processing 打开CL内核-每个工作项都会覆盖全局内存?
我正试图编写一个内核来获取字符串的字符频率 首先,下面是我现在为内核编写的代码:Parallel processing 打开CL内核-每个工作项都会覆盖全局内存?,parallel-processing,opencl,histogram,Parallel Processing,Opencl,Histogram,我正试图编写一个内核来获取字符串的字符频率 首先,下面是我现在为内核编写的代码: _kernel void readParallel(__global char * indata, __global int * outdata) { int startId = get_global_id(0) * 8; int maxId = startId + 7; for (int i = startId; i < maxId; i++)
_kernel void readParallel(__global char * indata, __global int * outdata)
{
int startId = get_global_id(0) * 8;
int maxId = startId + 7;
for (int i = startId; i < maxId; i++)
{
++outdata[indata[i]];
}
}
\u内核void readParallel(\u全局字符*indata,\u全局整型*outdata)
{
int startId=get_global_id(0)*8;
int maxId=startId+7;
对于(int i=startId;i
变量inData
在全局内存中保存字符串,outdata
是全局内存中256个int
值的数组。每个工作项从字符串中读取8个符号,并应在数组中增加相应的ASCII码。代码编译并执行,但outdata
中出现的字符总数少于inData
中的字符数。我认为问题在于工作项会覆盖全局内存。如果你能给我一些解决这个问题的建议,那就太好了
顺便说一下,。我是OpenCL的新手;-)而且,是的,我在其他问题中寻找解决方案。您正在体验全局内存使用不是原子的影响。按时间顺序发生的是: 一些工作组“线程”将
outData[123]
加载到一些寄存器r1
。。。大量的工作,阅读和写作,发生了,包括
outData[123]
同一工作组“线程”增量r1
。。。大量的工作,阅读和写作,发生了,包括
outData[123]
同一工作组“线程”将r1
写入outData[123]
因此,写入outData[123]
的值在读写之间的时间段内“丢弃”更新(我忽略了并行写入相互破坏的可能性,而不是其中一个成功)
您需要做的是:
- 使用原子操作——对代码的修改最少,但效率非常低,因为它在很大程度上序列化了您的工作,或者
- 使用特定于工作项、特定于扭曲和/或特定于工作组的部分结果,这些结果需要更少/更便宜的同步,并在完成大量工作后最终将它们合并
另一方面,@huseyintugrulbuyukisik正确地指出,您的代码使用带符号的
char
值对数组进行索引。要解决此问题,请执行以下操作之一:
- 对于数组索引,将那些
重新解释为char
(并在读取数组时重新解释)unsigned char
- 将字符值向上转换为更大的整数类型,并添加128以获得
输出数组的偏移量
- 将内核定义为仅支持字符(不高于127),在这种情况下,您可以忽略此问题(尽管如果您得到无效输入,这可能会导致崩溃)
- 如果您只关心字符的频率(但也可以在输入中包含非打印字符),则可以在对字符计数之前执行运行时检查