订阅业界RSS CSDN首页> 业界

释放 Python* 程序的强大并行性能

发表于2019-03-19 10:44| 来源intel| 作者intel

摘要:线程可组合性 在 Beta 版 英特尔 Python 分发版 * 中,我们引入了一个实验模块,该模块通过更好地组合来自不同 Python 模块的 线程 ,即提升计算密集型模块的线程 可组合性 ,释放了 Python 程序的强大性能。 当软件线程数量超过可用的硬件资源时,更好的线程组合性可避免低效的线程分配(被称作 过度订阅...

线程可组合性

Beta英特尔® Python 分发版* 中,我们引入了一个实验模块,该模块通过更好地组合来自不同 Python 模块的线程,即提升计算密集型模块的线程可组合性,释放了 Python 程序的强大性能。

当软件线程数量超过可用的硬件资源时,更好的线程组合性可避免低效的线程分配(被称作过度订阅)和相关性能问题,从而加速程序。

当任务池(例如,来自标准库的 ThreadPool)或 DaskJoblib 等库执行调用 Numpy/Scipy/PyDAAL 和其他计算密集型函数的任务时,可以最大限度地提升性能,然后使用英特尔® MKL /和英特尔® 线程构建模块(英特尔® TBB)对它们执行并行化。

模块使用英特尔® TBB 实施具有标准接口的Pool类,后者可替换 Python Pool ThreadPool 实施。通过猴子补丁技术,无需修改源代码便可支持基于 TBB 的并行化。

设置

英特尔® Python 分发版包含了您所需的一切工具。您也可以使用 conda install 英特尔conda-forge 默认渠道安装 tbb4py 2018.0.4 版本以上或之前的 tbb)或使用 pip install  PyPi 下载 - 请务必使用包含英特尔® MKL Numpy。此外,过度订阅开始影响性能,但是由于拥有足够多的可用 CPU,笔记本电脑通常不受影响。

让我们试试看!

在本示例中,我们需要 Dask 库,它可以使嵌套式并行性变得隐含,更适合 Python

conda install dask

现在,我们编写一个简单程序(QR 验证),文件名为 bench.py,该程序基于嵌套式并行性,可以打印计算花费的时间,如下所示:

import dask, time import dask.array as da x = da.random.random((100000, 2000), chunks=(10000, 2000)) t0 = time.time() q, r = da.linalg.qr(x) test = da.all(da.isclose(x, q.dot(r))) assert(test.compute()) # compute(scheduler="threads") by default print(time.time() - t0)

此处,Dask 将阵列分割为特定大小的块,并使用 P 个工作线程并行处理它们,P = CPU 的数量。每个 Dask 线程均执行昂贵的 numpy 运算,使用英特尔® MKL 在后台加速,因此它们是多线程运算。这导致嵌套式并行性,在默认 OpenMP 设置时运行的话,共有多达 P2 个线程。

按照以下方式运行(基准):

python bench.py

使用基于 TBB 的可组合线程释放更强大的性能:

python -m tbb bench.py

就这么简单!在我的设备(搭载 48 个逻辑 CPU)上,时间差异高达两倍。根据特定的设备配置和处理器数量,您可能得到截然不同的数据。

免责声明:TBB 模块不能很好地处理阻塞I/O运算,它仅适用于在操作系统中不进行阻塞的任务。该版本 TBB 模块为实验性质,可能未经过充分优化,可能不支持所有用例。