我正在使用Apple here
提供的OpenCL缩减示例经过几天的解剖,我了解了基础知识;我已将它转换为在c ++(Openframeworks)上运行或多或少可靠的版本,并在输入集中找到最大的数字。
然而,在这样做时,出现了一些问题如下:
为什么要使用多次传球?我能够减少所需的最多是两个;后者通过的元素数量非常少,因此非常不适合openCL过程(也就是说,坚持一次通过然后在cpu上处理结果会更好吗?)
当我设置'计数'对于一个非常高的数字(24M及以上)和float4的类型的元素数量,我得到不准确(或完全错误)的结果。这是为什么?
,任何人都可以解释在这里做了什么:
@BeforeParameter
而不是在这里做什么?
@AfterParameter
谢谢! 小号
答案 0 :(得分:1)
回答前两个问题:
\
可以将数百万个元素减少到几千个,并且设备利用率几乎可以达到100%。但最后一步非常棘手。因此,Apple实施决定先进行首次减少,而不是一次性保留所有内容并使多个线程空闲。然后使工作项适应新的减少问题,最后完成它。 Ii是OpenCL的一个非常具体的优化,但它可能不适用于C ++。
当我将'count'数量的元素设置为一个非常高的数字(24M 并且)和float4的类型,我得到不准确(或完全错误) 结果。这是为什么?
float32精度是其余的2 ^ 23。值高于24M = 1.43 x 2 ^ 24(浮点表示),误差范围为+/-(2 ^ 24/2 ^ 23)/ 2~ = 1。
这意味着,如果你这样做:
why are multiple passes used?
操作员错误在数据范围内,因此如果你在循环中重复这个错误就会出现大错误!
这在64位CPU中不会发生,因为32位浮点数学运算使用内部48位精度,因此避免了这些错误。但是如果你让浮点接近2 ^ 48,它们也会发生。但这不是正常“计数”整数的典型情况。
答案 1 :(得分:0)
问题在于32位浮点数的精度。你也不是第一个提出这个问题的人。 OpenCL reduction result wrong with large floats