更新(2014 年 8 月):我从未深入了解这一点,也从未在 Revolution 的论坛上得到任何反馈。然而,这个问题似乎已经在Revolution R 7.2(R 3.0.3,同样是学术版本)中得到了修复。我在下面运行了几百次 lme() 测试,正如预期的那样,所有测试都产生了相同的结果。[更新结束]
我刚刚在新PC上安装了Revolution R 7.0(R 3.0.2)的学术版本,并且下面的代码得到了奇怪的结果。每次运行代码时,都会给出不同的结果。在 CRAN-are 下,结果总是相同的(我认为应该是这样)。代码片段来自test.data.table()
版本 1.8.10 的测试 527,它向我指出了错误。
library(nlme)
all.equal(lme(distance ~ age, data=Orthodont), lme(distance ~ age, data=Orthodont))
我得到如下的东西,但每次都不同。
> all.equal(lme(distance ~ age, data=Orthodont), lme(distance ~ age, data=Orthodont))
[1] "Component 4: Component 2: Component 1: Mean relative difference: 1.774149e-08"
[2] "Component 7: Mean relative difference: 0.0003335902"
"有趣"的是nlme
包(lme()
是其中的一部分)本身是相同的,我卸载并重新安装以确保(包的 nlme_3.1-113.zip 文件是逐位相同的)。
我还没有足够的知识来深入了解。任何指示或想法将不胜感激。我也在革命论坛上发过帖子,但它似乎比这里人口少得多......
这是在64位Windows 8.1,64位R以及Intel i7-4770 CPU下,如果它很重要。当前版本的 Revolution R (R 3.0.2) 和以前的版本(2.15.3)都产生了意外的(对我来说)行为。CRAN-R 3.0.1 和 3.0.2 产生相同的结果。
Revolution R 的 sessionInfo() 输出:
> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] nlme_3.1-113 Revobase_7.0.0 RevoMods_7.0.0 RevoScaleR_7.0.0
[5] lattice_0.20-24 rpart_4.1-3
loaded via a namespace (and not attached):
[1] codetools_0.2-8 foreach_1.4.1 grid_3.0.2 iterators_1.0.6
[5] pkgXMLBuilder_1.0 revoIpe_1.0 tools_3.0.2 XML_3.98-1.1
更新 1:我已经将问题(遵循下面答案和评论中的一些指示)追溯到Revolution R使用Intel MKL BLAS库的事实。如果我切换到 CRAN 提供的 BLAS 库,问题就会消失。(注意:我自己对编译R的知识还不够,所以我还没有测试OpenBLAS和其他替代方案。在Revolution R中,只需重命名两个dll-s即可。
似乎其他人也得到了不一致的MKL结果。机器收费内部存在差异,即 all.equal()
为真,而identical()
为假。在我的案例中,不同的结果似乎有意义地大。
我已经在Revolution R的论坛上发布了这个问题,如果我得到回应,我会在这里更新。我想在这一点上,我的问题应该修改为"何时使用 MKL BLAS 以及何时使用 CRAN-R BLAS"。这不是速度(*)的问题,而是一致和正确的结果的问题。我将花更多时间寻找一个标准的测试套件(不确定这里的术语?)来检查R的输出与已知的正确输出。这是我喜欢data.table
的原因之一,它有自己的测试对最终用户可见。我知道我不应该期望一个包含所有(甚至大多数)包的单一测试,而是至少涵盖基本功能的东西。
(*) 速度取决于具体的工作流程。在这种特殊情况下,CRAN BLAS比MKL更快(两者都运行单线程)。在其他工作中,Revolution R的速度要快得多,这就是我研究它的原因。
猜测,Revo R 正在 CPU 内核上并行化它,并且重新组合并行事物的算术并不总是关联的。换句话说,这取决于操作的顺序。如果线程以不同的顺序完成,如果内核必须做其他事情,就会发生这种情况,那么结果会以不同的顺序相加,并且 (a+b)+c 并不总是等于浮点中的 a+(b+c)......
要检查一下,有没有办法告诉Revo R只使用一个CPU内核?