与OpenCL的还原例如导致结果不准确

我与苹果提供here与OpenCL的还原例如导致结果不准确

后解剖这几天,我了解的基础知识OpenCL的减少例如工作;我已经将它转换为在C++(Openframeworks)上可靠运行的版本,并在输入集中找到最大的数字。

然而,这样做,有几个问题已经出现如下:

  • 为什么使用多遍?我能够减少的最多的是两个;后者通过只占用非常少的元素,因此非常不适合openCL进程(即,坚持一次通过然后处理cpu上的结果会不会更好?)

  • 当我将'count'元素数设置为非常高的数字(24M以上)并将类型设置为float4时,我得到的结果不准确(或完全错误)。为什么是这样?

  • 在OpenCL内核

    ,任何人都可以解释什么正在这里进行:

while (i < n){ 

int a = LOAD_GLOBAL_I1(input, i);

int b = LOAD_GLOBAL_I1(input, i + group_size);

int s = LOAD_LOCAL_I1(shared, local_id);

STORE_LOCAL_I1(shared, local_id, (a + b + s));

i += local_stride;

}

,而不是正在这里做了什么?

#define ACCUM_LOCAL_I1(s, i, j) \ 

{ \

int x = ((__local int*)(s))[(size_t)(i)]; \

int y = ((__local int*)(s))[(size_t)(j)]; \

((__local int*)(s))[(size_t)(i)] = (x + y); \

}

谢谢! 小号

回答:

要回答第2个问题:

why are multiple passes used? 

减少数以百万计的元素到几千可以并行完成以几乎100%的设备利用率。但最后一步相当棘手。因此,苹果公司并没有把所有东西都保持在一个空闲状态,而是让多个线程闲置,而不是一次一个地减少;然后使工作项目适应新的减少问题,最后完成它。对于OpenCL,Ii是一个非常具体的优化,但它可能不适用于C++。

当我设置元素的“伯爵”号,以一个非常高的数字(24M 及以上)和类型为float4变量,我得到不正确(或完全错误的) 结果。为什么是这样?

float32的精度是2^23的余数。高于24M = 1.43 x 2^24(以浮点形式表示)的值在+/-(2^24/2^23)/ 2〜1的范围内有误差。

这意味着,如果您:

float A=24000000; 

float B= A + 1; //~1 error here

操作员错误在数据范围内,因此......如果您在循环中重复该操作,则会出现大错误!

这不会发生在64位CPU中,因为32位浮点运算使用内部48位精度,因此避免了这些错误。然而,如果你得到的浮动接近2^48,他们也会发生。但这不是正常“计数”整数的典型情况。

回答:

问题在于32位浮点的精度。你不是第一个问这个问题的人。 OpenCL reduction result wrong with large floats

以上是 与OpenCL的还原例如导致结果不准确 的全部内容, 来源链接: utcz.com/qa/261401.html

回到顶部