python - 随着使用更多内核,Python 多处理速度会变慢
问题描述
我正在使用 Python Multiprocessing 模块多次对角化(大而稀疏的)矩阵。我必须这样做一千次,所以决定在多处理中进行,因为我有 24 个内核。
代码如下所示:
import numpy as np
from scipy.sparse.linalg import eigsh
from scipy import sparse
def diag(param):
wf, vf = 0, 0
for i in range(10000):
num = np.random.rand()
.... # unrelated code producing the matrix with param and num
Mat = sparse.csc_matrix((data, (row, col)), shape=(8000, 8000))
w, v = eigsh(Mat, k=12)
.... #some other unrelated process updating wf and vf using w and v
return wf, vf
def Final(temp):
print("Process " % multiprocessing.current_process().name)
print(temp)
np.random.seed()
w0, v0 = diag(temp)
.... #unrelated process using w0 and v0
if __name__ == '__main__':
with Pool() as p:
print(p.map(Final, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
代码的其他部分无关紧要,因为在我的例子中,对 8000 x 8000 稀疏矩阵进行对角化是速率确定步骤。
当我不使用多处理时,该过程运行良好。但是,我实现多处理时的速度现在与使用的内核数成反比(!!)。我将不胜感激对此的任何输入,因为我理解池一般确实会使您的过程(一点点)变慢,但不会这么慢。我很困惑,因为 scipy 本质上没有实现多处理。
例子。通常在一个核心中,10 次对角化大约需要 2 秒。在 24 核中(在上面的示例中为 10 核!),大约需要 40 秒。
编辑:作为上下文,矩阵非常稀疏 - 8000 x 8000 矩阵中只有 48000 个条目。
编辑:已解决,但仍有问题。
我已经解决了这个问题,这很有趣,我想要你的意见。
问题如下:当 scipy.sparse 对角化一个大于某个阈值的矩阵时,它会自动进行多线程处理(我用 top. 进行了检查)。但是,与使用单核情况相比,这并没有显着提高速度。
我用自己的笔记本电脑检查了性能(双核,没什么花哨的!),性能比 24 核输出更好(!)(它的触发器数量略多,但仍然如此。)并意识到自动多线程是什么都不做,只是建立队列并阻止多处理。
因此,解决方案是使用 os 将 MKL 和 BLAS 设置为单线程,然后使用多线程 - 现在程序运行得很好。我现在很好奇,为什么首先使用 BLAS 多线程,但根本不使用多线程——这可能是开发人员的问题,但可能还有另一个复杂的解决方案。谁知道!
解决方案
推荐阅读
- javascript - 是否有导出与命名和默认导出相同的 const 的用例?
- mysql - 我有一个关于更新查询和数据库索引的示例问题
- python - 为什么 Python 3.6 中的字符串索引比 NumPy 索引慢 10 倍?
- c++ - 当我平均整数时丢失了多少信息?
- ruby-on-rails - 如何在rails中运行和提取mysql查询数据
- javascript - ExpressJS 下面是什么?
- apache-spark - Pyspark - 如何处理源文件中的'^M'字符
- node.js - 我将如何通过我的不和谐机器人上的 1 个命令中的链接执行另一个命令?
- c++ - C++ 中模板类的部分特化方法中的 std::enable_if
- rest - 谷歌 Firestore REST API