为什么Ryzen Threadripper的Numpy比Xeon慢得多?

时间:2020-07-07 20:19:11

标签: python performance numpy intel amd-processor

我知道Numpy可以使用不同的后端,例如OpenBLAS或MKL。我还读到MKL已针对Intel进行了优化,因此通常人们建议在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)

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

  • Intel Xeon E5-1650 v3 上,此代码使用 12个内核中的6个 0.7s 中执行。
  • AMD Ryzen 5 2600 上,此代码使用所有12个内核 1.45s 中执行。
  • AMD Ryzen Threadripper 3970X 上,此代码使用所有64个内核 1.55s 中执行。

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

  • 对于 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上,线性代数是否比六年前的Intel Xeon慢得多?? (也在更新3中解决)
  2. 从对CPU负载的观察来看,Numpy似乎在所有三种情况下都使用了多核环境。即使Threadripper的物理核心数量几乎是Ryzen 5的六倍,这又怎么可能呢? (另请参阅更新3)
  3. 是否可以采取任何措施来加快Threadripper上的计算速度? (在更新2中部分回答)

更新1: OpenBLAS版本为0.3.6。我在某处读到,升级到新版本可能会有所帮助,但是,在OpenBLAS更新到0.3.10的情况下,top的性能在AMD Ryzen Threadripper 3970X上仍为1.55s。


更新2:将Numpy的MKL后端与环境变量testfunc(如here所述)结合使用,可减少MKL_DEBUG_CPU_TYPE=5的运行时间AMD锐龙Threadripper 3970X仅为0.52s,这实际上或多或少令人满意。 FTR,通过testfunc设置此变量在Ubuntu 20.04上对我不起作用。同样,从Jupyter内部设置变量也不起作用。因此,我将其放入现在可以使用的~/.profile中。无论如何,执行速度比旧的Intel Xeon快35%,这是我们所能得到的,还是可以从中得到更多?


更新3:我尝试MKL / OpenBLAS使用的线程数:

run time by the number of threads and library

运行时间以秒为单位报告。每栏的最佳结果都带有下划线。我为此测试使用了OpenBLAS 0.3.6。该测试的结论:

  • 使用OpenBLAS的Threadripper的单核性能要比Xeon的单核性能好一些(快11%),但是当使用Xeon时,其单核性能甚至更好。使用MKL(速度提高了34%)。
  • 使用OpenBLAS的Threadripper的多核性能比Xeon的多核性能差劲。这是怎么回事?
  • 使用MKL时,Threadripper的整体性能优于Xeon (比Xeon快26%至38%)。 Threadripper使用16个线程和MKL(比Xeon快36%)实现了总体最佳性能。

更新4:仅用于澄清。不,我不认为(a)this或(b)that回答了这个问题。 (a)表明“ OpenBLAS的性能几乎与MKL一样” ,这与我观察到的数字强烈矛盾。根据我的数据,OpenBLAS的性能比MKL差很多。问题是为什么。 (a)和(b)都建议结合使用~/.bashrc和MKL以实现最佳性能。这可能是正确的,但它都不能解释为什么 OpenBLAS慢了。两者都没有解释,为什么即使使用MKL和MKL_DEBUG_CPU_TYPE=5 32核Threadripper也仅比拥有6年历史的6核Xeon 快36%。

2 个答案:

答案 0 :(得分:1)

我认为这应该有所帮助:

“图表中的最佳结果是使用MKL且环境为var MKL_DEBUG_CPU_TYPE = 5的TR 3960x。它明显优于仅来自MKL的低优化代码路径。并且,OpenBLAS的效果与MKL几乎一样MKL_DEBUG_CPU_TYPE = 5集。” 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/?sort=new

答案 1 :(得分:1)

尝试使用AMD优化的BLIS库是否有意义?

也许我缺少(误解)了一些东西,但是我认为您可以使用BLIS代替OpenBLAS。唯一的潜在问题可能是AMD BLIS针对AMD EPYC进行了优化(但是您正在使用Ryzen)。我对结果非常好奇,因为我正在购买服务器以供工作,并且正在考虑使用AMD EPYC和Intel Xeon。

以下是相应的AMD BLIS库: https://developer.amd.com/amd-aocl/