【问题标题】:R performance on Ryzen+Ubuntu: openBLAS/MKL, Rcpp and other improvements?Ryzen+Ubuntu 上的 R 性能:openBLAS/MKL、Rcpp 等改进?
【发布时间】:2020-08-27 15:45:41
【问题描述】:

我正在尝试在 Ubuntu 20.04、Microsoft R 3.5.2 和 Intel MKL 上从 Ryzen 3 3950x 16 核机器上实现最大值,并且 RCpp 代码使用 Sys.setenv(MKL_DEBUG_CPU_TYPE=5) 标头编译。

以下是我想要优化的主要操作:

  1. 快速多元随机正态法(我使用 Armadillo 版本):
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;

// [[Rcpp::export]]
arma::mat mvrnormArma(int n, arma::vec mu, arma::mat sigma) {
  int ncols = sigma.n_cols;
  arma::mat Y = arma::randn(n, ncols);
  return arma::repmat(mu, 1, n).t() + Y * arma::chol(sigma);
}

  1. Fast SVD(我发现base::svd 的性能优于我目前发现的任何Rcpp 实现,包括arma::svd("dc"),可能是由于U,S,V 尺寸不同)。

  2. 快速矩阵乘法用于各种结果(找到用 C 编写的代码,用基础 R 重写了所有代码,并且由于多核与以前的 1 核性能相比,我发现了巨大的改进。可以基础 R 矩阵运算进一步改进?)


我尝试了R4.0.2openBLAS 的各种设置(通过Ropenblas 包),玩过各种Intel MKL 版本,研究了AMD 的BLISlibflame(我不知道如何使用 R 进行测试)。

总体而言,此设置能够比配备 i7-8750h 和 Microsoft R 3.5.1(使用工作 MKL)的笔记本电脑高出约 2 倍,而基于 6 核与 16 核(以及更快的 RAM),我预计至少3-3.5 倍的改进(基于,例如,cinebench 和类似的性能基准)。

如何进一步改进此设置?

我的主要问题/疑问

首先,我注意到当前设置在使用 1 个工作人员运行时,在查看 top 调用时使用了大约 1000-1200% 的 cpu。通过实验,我发现生成两个并行工作程序会占用大部分 CPU,大约 85-95%,并提供最佳性能。例如,3 个工作人员使用了整体 100%,但在某处出现了瓶颈,由于某种原因大大降低了性能。

我猜这是来自 R/MKL 的限制,或者是在编译 Rcpp 代码时出现的限制,因为 10-12 核似乎有些奇怪。 在编译 Rcpp 代码时可以通过一些提示来改进这一点

其次,我确定我没有使用最佳的 BLAS/LAPACK/etc 驱动程序来完成这项工作。我的猜测是正确编译的R4.0.2 应该比Microsoft R3.5.2 快得多,但我完全不知道我错过了什么,AVX/AVX2 是否被正确调用/使用,我还应该用机器尝试什么?

最后,我看到了调用/使用 AMD BLIS/libflame for R 的零指南。如果这是微不足道的,将不胜感激任何提示/帮助。

【问题讨论】:

    标签: r linux rcpp lapack intel-mkl


    【解决方案1】:

    在弹出任何其他(希望更好)答案之前,我会在此处发布我通过猜测得出的最新发现。希望拥有类似机器的人会发现这很有用。如果出现任何其他改进,将尝试扩展答案。


    1. 干净的 R 编译指南。似乎已经过时了,但希望没有什么遗漏:

      Speed up RcppArmadillo: How to link to OpenBlas in an R package

      OpenBLAS and IntelMKL examples + Rstudio

    2. OpenBLAS 在我的 Ryzen + Ubuntu 配置上效果不佳;使用 3.10 BLAS,使用 zen2 提示编译,使用所有 CPU 内核,但非常糟糕。 top 报告 R 实例的使用率为 3200%,但总 CPU 使用率不会上升超过 20-30%。因此,性能至少比英特尔 MKL 慢 3 倍。

    3. 英特尔MKL。直到 2019 年的版本都可以使用 MKL_DEBUG_CPU_TYPE workaround。可以确认intel-mkl-64bit-2019.5-075 有效。

      对于2020.0-088 之后的更高版本,different workaround 是 需要。根据我的基准测试,性能没有看到任何 改进,但是,这可能会随着未来的 MKL 版本而改变。

    4. 每个实例 10-12 的硬编码上限似乎由多个环境变量控制。我找到了以下列表as per this old guide。这些可能会随着以后的版本而改变,但似乎适用于2019.5-075

    export MKL_NUM_THREADS=2
    export OMP_NESTED="TRUE"
    export MKL_DOMAIN_NUM_THREADS="MKL_BLAS=1"
    export OMP_NUM_THREADS=1
    export MKL_DYNAMIC="TRUE"
    export OMP_DYNAMIC="FALSE"
    

    玩弄各种配置后,我发现减少线程数量并产生更多工人,对于我测试过的特定基准,性能显着提高(大约 3- 4折)。尽管声称的 CPU 使用率与配置的多核变体相似,但 2 个工作人员每人使用 16 个线程(总计约 70% 的 cpu 利用率)比 16 个工作人员每人使用 2 个线程(同样,类似的 cpu 利用率)慢得多。结果可能因不同的任务而异,因此这些似乎是每个较长任务的首选参数。

    1. AMD BLIS。将此作为 MKL BLAS 的替代品进行测试,目前仅进行试验,但性能似乎与所有修复的英特尔 MKL 相当。通过perf 检查是否实际使用了 BLIS,对于我的基准测试,调用了bli_dgemmsup_rd_haswell_asm_6x8mbli_daxpyv_zen_int10 和其他人。尚不确定编译 BLIS 的设置是否最佳。 考虑到我的具体基准,这里的要点可能是 MKL 和 BLIS 实际上都在推动 CPU 的最大值......或者至少两个库都进行了类似的优化。

    坚持使用 AMD BLIS 的重要缺点:在使用数月后注意到,但似乎存在一些未解决的问题,我不知道将 BLIS 或 LAPACK 打包到 AMD 库中。我注意到不可复制的随机矩阵乘法问题(本质上是hitting into this problem),可以通过切换回 MKL 库来解决。我不能说我构建 R 的方式或实际的库是否有问题,所以只是一个警告。

    【讨论】:

    • 我在 Ubuntu 中使用 AMD 2700x 与 R 链接了最新的 2020 版 MKL,但我还没有尝试设置 CPU DEBUG 标志的技巧。我注意到 R 中的矩阵乘法在单个线程上的速度提高了约 3 倍。我(天真的)猜测是英特尔修复了歧视 AMD CPU 的错误,所以我会考虑首先进行基准测试以确保它仍然是必要的。
    • @thc 好点,看来英特尔正在慢慢实施 AMD cpus。 recent blogpost 深入研究了 2020 MKL,并提出了其他解决方法。也需要测试这些。
    • @thc 从2019.5-075 升级到2020.2-108 会导致约10% 的性能下降(大致,但始终如一)。在应用libfakeintel.so hack 时,性能恢复到以前的水平,但没有任何改善。这仍然是一个很好的结果,因为这种解决方法感觉比 DEBUG 标志更面向未来。
    • 酷,感谢您的全部测试,我相信其他人一定会欣赏结果。我不确定我是否同意这种新的解决方法更具未来性,尽管英特尔可以轻松地将其锁定得更好。
    猜你喜欢
    • 2018-02-22
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多