浮点计算既不是关联的,也不是处理器上的分配.所以,
(a + b) + c
不等于 a + (b + c)
和a * (b + c)
不等于a * b + a * c
有没有办法执行不会给出不同结果的确定性浮点计算.它对于单处理器来说是确定性的,但是如果线程增加一个总和,它在多线程程序中就不是确定性的,因为线程可能有不同的交错.
所以我的问题是,如何在多线程程序中实现浮点计算的确定性结果?
Ste*_*non 17
浮点是确定性的.在相同硬件上运行的相同浮点运算始终产生相同的结果.没有黑魔法,噪音,随机性,模糊测试或人们通常归因于浮点的任何其他事物.牙仙没有出现,取你的结果的低位,并在你的枕头下留下四分之一.
现在,认为,这通常用于大规模并行计算某些阻止算法是在其中的浮点运算的执行顺序,这可导致在整个运行非比特精确的结果方面的非确定性.
你能为这个做什么?
首先,确保你实际上不能忍受这种情况.您可能尝试在并行计算中强制执行排序的许多事情都会损害性能.就是这样.
我还要注意,尽管被阻塞的算法可能会引入一定数量的非确定性,但它们通常会提供比未经阻塞的串行算法更小的舍入误差的结果(令人惊讶但却是真实的!).如果你能忍受一个天真的串行算法产生的错误,你可能会遇到并行阻塞算法的错误.
现在,如果你真的,真的,需要跨运行的完全重现性,这里有一些建议往往不会对性能产生太大的负面影响:
不要使用可以重新排序浮点计算的多线程算法.问题解决了.这并不意味着您根本不能使用多线程算法,只需要确保每个单独的结果仅由同步点之间的单个线程触及.请注意,如果正确完成,通过减少核心之间的D $争用,这实际上可以提高某些体系结构的性能.
在还原操作中,您可以让每个线程将其结果存储到数组中的索引位置,等待所有线程完成,按顺序累积数组的元素.这会增加少量的内存开销,但通常是可以容忍的,特别是当线程数"很小"时.
找到提升并行性的方法.而不是计算24个矩阵乘法,每个矩阵乘法使用并行算法,并行计算24个矩阵乘积,每个矩阵乘积使用串行算法.这也有利于性能(有时非常有用).
还有很多其他方法可以解决这个问题.他们都需要思考和关心.并行编程通常会.