我使用AMD's two-stage reduction example使用浮点精度计算0到65 536之间所有数字的总和。不幸的是,结果不正确。但是,当我修改我的代码时,我计算了65 536个较小数字的总和(例如1),结果是正确的。
我无法在代码中发现任何错误。由于浮动类型,我可能会得到错误的结果吗?如果是这种情况,解决问题的最佳方法是什么?
答案 0 :(得分:2)
这是副作用"使用有限精度CPU或GPU来汇总浮点数。精度取决于算法和值相加的顺序。背后的理论和实践在Nicholas J,Higham的论文中有所解释
浮点求和的准确性
修复方法是使用更智能的算法,如Kahan求和算法
https://en.wikipedia.org/wiki/Kahan_summation_algorithm
高海姆的论文也有其他选择。
这个问题说明了基准测试的本质,基准测试的第一条规则是获得 正确答案,使用现实数据!
答案 1 :(得分:1)
您的内核或主机应用程序的编码可能没有错误。问题在于单精度浮点。
正确的总和是:65537 * 32768 = 2147516416,它需要31位来表示二进制(10000000000000001000000000000000)。 32位浮点数只能精确保持整数2 ^ 24。
"绝对值小于[2 ^ 24]的任何整数都可以用单精度格式精确表示" "Floating Point" article, wikipedia
这就是为什么在小于或等于2 ^ 24时得到正确的总和。如果使用单精度进行完整求和,无论您在哪个设备上执行内核,最终都会失去准确性。您可以采取一些措施来获得正确的答案: