由于for循环,OpenCL丢失了变量值

时间:2013-11-12 11:26:43

标签: for-loop opencl

我有以下opencl代码:

__constant SomeConstants[] = { 5, 7, 242, 74 };

long aslong(__global int * arr, int offset) {
    return ... <CalculateLong> ...;
};

void calcSomething(__global int * numArray, int * result) {
    long tempArray[] = { numArray[0], numArray[1], numArray[2], numArray[3] };

    long x0 = (result[0] = aslong(numArray, 0)) + tempArray[0];
    long x1 = (result[1] = aslong(numArray, 8)) + tempArray[1];
    long x2 = (result[2] = aslong(numArray, 16)) + tempArray[2];
    long x3 = (result[3] = aslong(numArray, 32)) + tempArray[3];
    // do some calculations here
    result[0] = x0;
    result[1] = x1;
    result[2] = x2;
    result[3] = x3;

};

__kernel void calc(__global int * numArray, __global long * sum) {
    long arr[] = { SomeConstants[0], SomeConstants[1], SomeConstants[2], SomeConstants[3] };
    calcSomething(numArray, arr);
    sum[get_global_id(0)] = arr[0];
    sum[get_global_id(0)+1] = arr[1];
    sum[get_global_id(0)+2] = arr[2];
    sum[get_global_id(0)+3] = arr[3];
};

上面的代码按预期工作,但问题是,我无法为calcSomething添加更多计算。当我向calcSomethig添加一个空循环时,如下所示:

void calcSomething(__global int * numArray, int * result) {
    long tempArray[] = { numArray[0], numArray[1], numArray[2], numArray[3] };

    long x0 = (result[0] = aslong(numArray, 0)) + tempArray[0];
    long x1 = (result[1] = aslong(numArray, 8)) + tempArray[1];
    long x2 = (result[2] = aslong(numArray, 16)) + tempArray[2];
    long x3 = (result[3] = aslong(numArray, 32)) + tempArray[3];

    for (int i = 0; i < 18; i++) {}

    result[0] = x0;
    result[1] = x1;
    result[2] = x2;
    result[3] = x3;

};

result [0]和result [1]存储正确的值,但result [2]和result [3]绝对错误。通过注释for循环,结果[2]和3是正确的...任何想法在调用for循环时x0,x1,x2和x3发生了什么?

1 个答案:

答案 0 :(得分:1)

已编辑答案:您的问题位于操作中:

sum[get_global_id(0)] = arr[0];
sum[get_global_id(0)+1] = arr[1];
sum[get_global_id(0)+2] = arr[2];
sum[get_global_id(0)+3] = arr[3];

您正在使用重叠索引的sum[]全局数组。但是, MANY 工作项会写入相同的内存,从而产生未定义的结果。 您需要修复重叠,或者对全局变量执行原子操作。

示例:

 gid 0 -> Write to sum[0,1,2,3]
 gid 1 -> Write to sum[1,2,3,4]
 //....

for循环根本不与问题有关。您只是在多线程环境中看到不同计划的影响。但这不是问题的根源。

进一步修改 代码存在与OpenCL无关的问题。上面已经描述了OpenCL的唯一问题。

有很多地方C变量被错误地压缩或隐藏,然后被错误地使用。例如,在aslong()中,添加了8个连续的整数来形成一个长整数,但是长整数是由8个字节组成的,而不是8个。