为什么带有 Ryzen Threadripper 的 Numpy 比 Xeon 慢这么多?

the*_*0ID 45 python performance numpy intel amd-processor

我知道 Numpy 可以使用不同的后端,如 OpenBLAS 或 MKL。我还读到 MKL 针对英特尔进行了大量优化,所以通常人们建议在 AMD 上使用 OpenBLAS,对吗?

我使用以下测试代码:

import numpy as np

def testfunc(x):
    np.random.seed(x)
    X = np.random.randn(2000, 4000)
    np.linalg.eigh(X @ X.T)

%timeit testfunc(0)
Run Code Online (Sandbox Code Playgroud)

我已经使用不同的 CPU 测试了这段代码:

  • 英特尔至强 E5-1650 v3 上,此代码使用12 个内核中的 6 个0.7 秒内执行。
  • AMD Ryzen 5 2600 上,此代码使用所有 12 个内核1.45 秒内执行。
  • AMD Ryzen Threadripper 3970X 上,此代码使用所有 64 个内核1.55 秒内执行。

我在所有三个系统上都使用相同的 Conda 环境。根据np.show_config(),Intel 系统为 Numpy ( libraries = ['mkl_rt', 'pthread'])使用 MKL 后端,而 AMD 系统使用 OpenBLAS ( libraries = ['openblas', 'openblas'])。CPU 核心使用率是通过top在 Linux shell 中观察来确定的:

  • 对于Intel Xeon E5-1650 v3 CPU(6 个物理内核),它显示 12 个内核(6 个空闲)。
  • 对于AMD Ryzen 5 2600 CPU(6 个物理内核),它显示 12 个内核(无空闲)。
  • 对于AMD Ryzen Threadripper 3970X CPU(32 个物理内核),它显示 64 个内核(无空闲)。

上述观察引起以下问题:

  1. 使用 OpenBLAS 的最新 AMD CPU 上的线性代数比使用 6 年历史的 Intel Xeon得多,这正常吗?(也在更新 3 中提到)
  2. 从 CPU 负载的观察来看,看起来 Numpy 在所有三种情况下都利用了多核环境。尽管 Threadripper 的物理内核数量几乎是 Ryzen 5 的六倍,但它怎么可能比 Ryzen 5 还要慢?(另见更新 3)
  3. 有什么办法可以加快 Threadripper 的计算速度吗?(在更新 2 中部分回答)

更新 1: OpenBLAS 版本为 0.3.6。我在某处读到,升级到更新版本可能会有所帮助,但是,随着 OpenBLAS 更新到 0.3.10,testfuncAMD Ryzen Threadripper 3970X的性能仍然是 1.55s。


更新2:在与所述环境变量一起使用MKL后端为numpy的MKL_DEBUG_CPU_TYPE=5(如所描述的在这里)减少的运行时间testfunc上AMD Ryzen Threadripper 3970X仅0.52s,这实际上是或多或少满足。FTR,通过设置这个变量~/.profile在 Ubuntu 20.04 上对我不起作用。此外,从 Jupyter 内部设置变量不起作用。所以我把它放在~/.bashrc现在可以工作的地方。无论如何,性能比旧的英特尔至强快 35%,这就是我们所得到的,还是我们可以从中获得更多?


更新 3:我玩弄 MKL/OpenBLAS 使用的线程数:

运行时间由线程和库的数量决定

运行时间以秒为单位报告。每列的最佳结果都带有下划线。我在这个测试中使用了 OpenBLAS 0.3.6。本次测试的结论:

  • 使用 OpenBLAS 的 Threadripper的单核性能比 Xeon 的单核性能要好一些(快 11%),但使用 MKL 时其单核性能甚至更好(快 34%)。
  • 使用 OpenBLAS 的 Threadripper的多核性能比 Xeon 的多核性能离谱。这里发生了什么?
  • 当使用 MKL 时,Threadripper 的整体性能比 Xeon 好(比 Xeon 快 26% 到 38%)。使用 16 个线程和 MKL(比 Xeon 快 36%)的 Threadripper 实现了整体最佳性能。

更新 4:只是为了澄清。不,我认为(a)这个或(b)不能回答这个问题。(a) 表明"OpenBLAS 几乎和 MKL 一样好",这与我观察到的数字强烈矛盾。根据我的数据,OpenBLAS 的性能比 MKL 差得离谱。问题是为什么。(a) 和 (b) 都建议MKL_DEBUG_CPU_TYPE=5与 MKL 结合使用以实现最佳性能。这可能是对的,但这并不能解释为什么OpenBLAS如此缓慢。无论它说明,即使MKL为什么和MKL_DEBUG_CPU_TYPE=532核Threadripper比六岁的6核Xeon快36%

pol*_*iki 1

我认为这应该有帮助:

“图表中的最佳结果是在环境变量 MKL_DEBUG_CPU_TYPE=5 的情况下使用 MKL 的 TR 3960x。而且它比单独使用 MKL 的低优化代码路径要好得多。而且,OpenBLAS 几乎与 MKL_DEBUG_CPU_TYPE=5 的 MKL 一样好放。” https://www.pugetsystems.com/labs/hpc/How-To-Use-MKL-with-AMD-Ryzen-and-Threadripper-CPU-s-Effectively-for-Python-Numpy-And-Other-Applications- 1637/

如何设置:“通过在系统环境变量中输入 MKL_DEBUG_CPU_TYPE=5 使设置永久生效。” 这有几个优点,其中之一是它适用于 Matlab 的所有实例,而不仅仅是使用 .bat 文件打开的实例' https://www.reddit.com/r/matlab/comments/dxn38s/howto_force_matlab_to_use_a_fast_codepath_on_amd/?排序=新