我试图编写一个内核来获取字符串的字符频率。
首先,这是我现在为内核编写的代码:
_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]];
}
}
变量inData
将字符串保存在全局内存中,outdata
是全局内存中256个int
值的数组。每个工作项从字符串中读取8个符号,并应在数组中增加相应的ASCII代码。代码编译并执行,但outdata
包含的总出现次数少于inData
中的字符数。我认为问题是工作项会覆盖全局内存。如果你能给我一些解决这个问题的技巧,那就太好了。
答案 0 :(得分:1)
您正在体验使用全局记忆不是原子(C++-oriented description of what those are或another description by the Intel TBB folks)的效果。按时间顺序发生的是:
某些工作组“线程”会将
中outData[123]
加载到某个注册表r1
......很多工作,阅读和写作都会发生,包括在内
outData[123]
...相同的工作组“线程”增加
r1
......很多工作,阅读和写作都会发生,包括在内
outData[123]
...相同的工作组“线程”将
r1
写入outData[123]
因此,写入outData[123]
的值会丢弃“读取和写入之间的时间段内的更新(我忽略了并行写入相互破坏而不是其中一个获胜的可能性)。
您需要做的是:
在一个不相关的说明中,正如@huseyintugrulbuyukisik正确指出的那样,您的代码使用带符号的char
值来索引数组。要解决此问题,请执行以下操作之一:
char
为unsigned chars
(并在读取数组时重新解释。outArray
的偏移量。