我正在尝试使用英特尔的MKL来提高Python 3.6中NumPy的性能。通过新的anaconda安装,我使用:
创建了一个MKL环境conda create -n idp intelpython3_core python = 3
正如本article所述, 似乎MKL有内部阈值来决定是否使用线程。似乎这些阈值中的一个是由计算中使用的矢量大小给出的(明显的一种)。此阈值设置为矢量大小8192(至少对于我的机器)。当向量超过这个大小时,我可以使用4个线程观察我的python脚本(我有2个超线程核心)用于计算:
import numpy as np
x = np.random.rand(8193)
y = np.sin(x)
到目前为止,一切都按计划进行。
除了线程部分,MKL"具有高度优化,线程化和矢量化的数学函数,可最大限度地提高每个处理器系列的性能。 (read here)。由于我经常处理的问题不超过矢量大小阈值,我对通过线程获得的性能增加不感兴趣,但更多的是在MKL的优化数学函数中。不幸的是,当矢量大小高于阈值时,似乎只使用了那些。
我已经编写了一个示例代码来测量不同大小的矢量的正弦运算的性能:
from timeit import default_timer as timer
import mkl
import numpy as np
mkl.set_num_threads(1)
print("MKL threads:%i" % mkl.get_max_threads())
np.random.seed(0)
Nop = int(1e4)
def func(x):
return np.sin(x)
def measure(x):
t1 = timer()
for i in range(0, Nop):
func(x)
t2 = timer()
diff = (t2 - t1)*1000.0
print("vec size: %i:" % len(x), end="")
print("\t time needed: %f ms" % diff)
x0 = np.random.rand(20000)
measure(np.array(x0[:8192]))
measure(np.array(x0[:8193]))
measure(np.array(x0[:8192]))
这些行:
import mkl
mkl.set_num_threads(1)
print("MKL threads:%i" % mkl.get_max_threads())
只是为了确保,性能的提升不是由于线程(我还检查了CPU的使用情况,它确实只使用了一个线程)
我得到了这些结果:
vec size: 8192: time needed: 8185.900477 ms
vec size: 8193: time needed: 436.843237 ms
vec size: 8192: time needed: 1777.306942 ms
如您所见,8193矢量的运行速度比8192矢量快约20倍。更令人困惑的是,在对更大的矢量进行计算之后,8193矢量的第二次运行速度比以前快了4倍。
现在我的问题:
PS: 我实际上在模拟中尝试了以下内容,我正在为我的硕士论文运行,其中涉及大量的正弦和余弦函数调用: 在计算任何其他内容之前添加此行:
np.sin(np.zeros(8193))
现在一切都快了50%。