我正在尝试理解我的 OpenCL 内核函数中发生的奇怪行为。我基本上是在尝试将包含十六进制的字符串转换为包含其十进制表示的字符串,但是由于我无法理解的原因,使用 GPU 和 CPU 运行相同的内核会产生不同的结果。
内核如下所示:
// yes, there's no result defined for the moment
__kernel void testKernel(__global uint message_length, __global char *message) {
size_t converted_message_length = message_length / 2;
char converted_message[converted_message_length];
// (1) hex to decimal conversion
for (size_t idx = 0, j = 0; idx < converted_message_length; idx++, j++) {
converted_message[idx] = (message[j] & '@' ? message[j] + 9 : message[j]) << 4;
j++;
converted_message[idx] |= (message[j] & '@' ? message[j] + 9 : message[j]) & 0xF;
printf("converted '%c%c' into '%i'\n", message[j - 1], message[j], converted_message[idx]);
}
// (2) this should be redundant, since I already print the content...
// but actually behaves differently with different device (CPU/GPU)
for (size_t idx = 0, j = 0; idx < converted_message_length; idx++, j++) {
printf("converted_message[%i]: '%i'\n", idx, converted_message[idx]);
}
现在,如果我将长度 testKernel
作为 4
函数的参数传递,以及包含十六进制值 3e2b
的输入字符串,我希望它们被转换为十进制 {{1} } 和 62
(see this table 用于十六进制 -> 十进制转换)。
而且,如果我使用我的 CPU (Intel(R) Core(TM) i9-9880H) 运行内核,我确实可以看到以下转换发生:
43
但是,如果我使用我的 GPU (AMD Radeon Pro 5500M) 运行相同的内核,我会看到以下结果:
converted '3e' into '62'
converted '2b' into '43'
converted_message[0]: '62'
converted_message[1]: '43'
似乎 converted '3e' into '62'
converted '2b' into '43'
converted_message[0]: '0' <-- why it is 0 ???
converted_message[1]: '0' <-- why it is 0 ???
在循环 converted_message
内成功写入,但是当我进入 (1)
循环内时,它的值丢失了。这怎么可能?是不是 OpenCL 在幕后执行了一些奇怪的优化,只有在 GPU 中运行时才会表现出来?