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),在这种情况下,您可以忽略此问题(尽管如果您得到无效输入,这可能会导致崩溃)
  • 如果您只关心字符的频率(但也可以在输入中包含非打印字符),则可以在对字符计数之前执行运行时检查

字符也可以是负数,并在c>127的输入数组中下溢。无符号字符为我工作,使用无符号字符和原子操作为我完成了这项工作。谢谢。@j_ice:你对一个好的答案表示感谢,并对其进行上浮表决;如果它解决了你的问题,你将其标记为已接受。如果没有,其他人可以解释在评论中,缺少/不正确的地方。