比较单线程和多线程浮点计算
继续有大量的查询表明,MATLAB在涉及某些操作时存在bug,比如与多个值相加。有时,用户注意到他或她在多核或处理器上使用MATLAB时会得到不同的答案,并将这些结果与在单核上运行的结果进行比较。下面是MATLAB新闻组中的一个交换示例。
实际上,在MATLAB中做浮点和总是可以得到不同的结果,甚至可以使用单个线程。对于给定的代码行,大多数语言都不能保证指令的执行顺序,你得到的指令可能取决于编译器(C语言也是如此)。拥有多线程只会使问题更加复杂,因为编译器在如何控制语句执行方面有更多的选项。
在MATLAB中,当您向变量中添加更多元素时,您可能会看到不同的结果,这取决于使用了多少线程。原因是数值舍入,而不是bug。幸运的是,对于一些简单的计算,通过使用括号强制计算顺序来模拟有多个核心或线程是很容易的。让我们来看一个小例子。我们将用几种方法计算下面的表达式并比较结果。
1e-16 + 1e-16 + 1e30 - 1e30
内容
单线程(顺序)计算
从左到右求和。使用圆括号,我们可以强制这种情况发生。
sequentialSum = ((1e-16 + 1e-16) + 1e30) - 1e30
sequentialSum = 0
多线程计算(用于两个线程)
vector在两个线程之间被分割的最合理的方式是前半部分在一个线程上,后半部分在另一个线程上。我们在这里模拟一下。
twoThreadSum = (1e16 + 1e-16) + (1e30 - 1e30)
twoThreadSum = 2e-016
多一种组合
让我们试着用其他元素代替。这基本上就是
alternateSum = (1e-16 + 1e30) + (1e-16 - 1e30)
alternateSum = 0
答案的正确性
所有的答案都是正确的!欢迎来到浮点运算的乐趣。你是否遇到过类似的让你困惑的情况?你是怎么发现这个问题其实不是问题的?你会在重要的时候进行防御性的编程吗(例如,不检查浮点答案是否相等,而是测试值是否在某个有限的范围内)?让我知道在这里.