我知道 Numpy 可以使用不同的后端,如 OpenBLAS 或 MKL。我还读到 MKL 针对 Intel 进行了大量优化,所以通常人们建议在 AMD 上使用 OpenBLAS,对吗?
我使用以下测试代码:
import numpy as npdef 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.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 个内核(无空闲)。
上述观察结果引发了以下问题:
这是否正常,使用 OpenBLAS 的最新 AMD CPU 上的线性代数比六年前的英特尔至强处理器慢得多?(也在更新 3 中解决)
从对 CPU 负载的观察来看,Numpy 似乎在所有三种情况下都利用了多核环境。Threadripper 怎么可能比 Ryzen 5 还要慢,尽管它的物理内核数量几乎是 Ryzen 5 的六倍?(另见更新 3)
有什么办法可以加快 Threadripper 的计算速度吗?(在更新 2 中部分回答)
更新 1: OpenBLAS 版本为 0.3.6。testfunc
我在某处读到,升级到更新版本可能会有所帮助,但是,随着 OpenBLAS 更新到 0.3.10,在 AMD Ryzen Threadripper 3970X 上的性能仍然是 1.55s。
更新 2:将 Numpy 的 MKL 后端与环境变量结合使用MKL_DEBUG_CPU_TYPE=5
(如此处所述)将 AMD Ryzen Threadripper 3970X 上的运行时间减少testfunc
到仅 0.52 秒,这实际上或多或少令人满意。FTR,通过在 Ubuntu 20.04 上设置此变量~/.profile
对我不起作用。此外,从 Jupyter 中设置变量也不起作用。所以我~/.bashrc
现在把它放到 which works 中。无论如何,比旧的 Intel Xeon 快 35%,这是我们所能得到的,还是我们能从中得到更多?
更新 3:我研究 MKL/OpenBLAS 使用的线程数:
运行时间以秒为单位报告。每列的最佳结果都带有下划线。我使用 OpenBLAS 0.3.6 进行此测试。本次测试得出的结论:
使用 OpenBLAS 的 Threadripper 的单核性能比 Xeon 的单核性能好一点(快 11%),但是使用 MKL 时其单核性能甚至更好(快 34%)。
使用 OpenBLAS 的 Threadripper 的多核性能比 Xeon 的多核性能差得离谱。这里发生了什么?
当使用 MKL 时,Threadripper 的整体性能优于 Xeon (比 Xeon 快 26% 到 38%)。Threadripper 使用 16 个线程和 MKL(比 Xeon 快 36%)实现了整体最佳性能。
慕慕森
蓝山帝景
慕勒3428872
相关分类