新硬件运行R代码的速度比旧硬件慢

时间:2018-07-31 21:59:37

标签: r performance

为了测试新系统并了解性能,我重新运行了old R project,其中包含用于机器学习的定时代码。

新增功能Ryzen 7 2700X(8核,16线程;基本/加速时钟= 3.7 / 4.3 GHz),Fedora 28

旧版本:Intel i7 4710HQ(4核,8线程;基本/加速时钟= 2.5 / 3.5 GHz),Windows 7

结果令我震惊-新系统比旧系统慢20%以上。

非硬件差异:

  • Windows 7与Fedora 28(不知道这是否会影响性能,但是this post报告了很大的不同)。 Windows中的R默认情况下是否具有更多优化的库?
  • R的版本(Fedora:系统存储库中的R-3.5.0-4.fc28; Windows:不记得了)和所使用的软件包并不相同,但相差2年以上,我认为是较新的版本版本和硬件将具有性能优势。

运行7个线程或15个线程之间的差异仅为6%,因此并行化的伸缩性不是很好,但是我仍然希望更新和时钟频率更高的硬件能够更快地完成工作……而且当然可以不慢。

这是为什么?


编辑:我运行了许多带有不同线程数的方案,并打开和关闭了CPB和SMT。请注意,在某些情况下,系统使用率很低,因此应在误差范围内考虑接近的结果。

| user    | system | elapsed  | OS        | CPU       | Threads | Turbo/CPB | HT/SMT | Load average |  
|---------|--------|----------|-----------|-----------|---------|-----------|--------|--------------|  
| 126.421 | 0.532  | 2275.998 | Fedora 28 | R7 2700X  | 8       | ON        | OFF    | >42          |
| 126.583 | 0.541  | 2324.118 | Fedora 28 | R7 2700X  | 7       | ON        | OFF    | ?            |
| 136.636 | 0.574  | 2433.931 | Fedora 28 | R7 2700X  | 7       | OFF       | OFF    | ?            |
| 221.49  | 7.48   | 2679.77  | Windows 7 | i7 4710HQ | 7       | ON        | ON     | ?            |
| 155.427 | 0.555  | 3233.690 | Fedora 28 | R7 2700X  | 15      | ON        | ON     | >100         |
| 168.859 | 0.609  | 3247.277 | Fedora 28 | R7 2700X  | 15      | ON        | ON     | ?            |
| 173.312 | 0.650  | 3250.313 | Fedora 28 | R7 2700X  | 16      | ON        | ON     | >70          |
| 161.403 | 0.611  | 3270.098 | Fedora 28 | R7 2700X  | 14      | ON        | ON     | ?            |
| 162.120 | 0.540  | 3442.758 | Fedora 28 | R7 2700X  | 7       | ON        | ON     | ?            |

总结:线程越多越好,CPB = ON似乎总是有帮助的,但是将SMT = OFF设置可获得最快的结果。

偶尔观察到平均负载会发现它们变得很高,远远大于铁心的数量。也许上下文切换会降低性能吗?

1 个答案:

答案 0 :(得分:0)

使用更高内核数的CPU导致性能降低的原因是嵌套并行性,这是由于caret和模型(在这种情况下为xgboost)都进行了并行化。高负载平均表明,这会使CPU过载,并导致执行时间变慢。

来自caret的{​​{3}}:

  在各自的控制文件中,分别为

train,rfe,sbf,bag和avNNet提供了一个额外的参数,称为allowParallel,默认为TRUE。设为TRUE时,如果注册了并行后端(例如doMC),则代码将并行执行。当allowParallel = FALSE时,并行后端始终被忽略。用例是当rfe或sbf调用训练时。 如果使用带有P处理器的并行后端,则这些功能的组合将创建P ^ 2进程。

如果P个CPU内核有P ^ 2个进程,则意味着每个内核的过载系数是P。因此,更高的内核数CPU实际上可能由于过载更多而性能更差。

解决方案是通过以下两种方法来避免嵌套并行性:

  • 使用模型的并行化,而不使用并行后端。可以通过设置caret的{​​{1}}来完成。

  • 使用并行后端,而不让模型并行化。对于allowParallel = FALSE,可以通过设置xgboost来完成。可以在nthread = 1caret::train中设置此参数,例如。 caretEnsemble::caretList

tuneList=list(xgbLinear=caretModelSpec(method="xgbLinear", nthread=1))作者的documentation有助于说明每种方法何时更有利:在单个长期运行的模型中,前一种解决方案;如果有很多重采样,则后者。因为:

  

通常,我们希望并行化运行时间最长的部分   算法。


使用后一种方法,在15个工作人员后端(SMT = ON,CPB = ON,Fedora 28)上,Ryzen 7 2700X的总体执行时间缩短了约2.8倍,从而大大缩短了时间:

caret

仅训练## user system elapsed ## 109.160 0.638 1168.102 模型的执行时间(在2433秒或40.55分钟是总执行时间的大部分)减少了约8倍,至5分钟。