与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