Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
由于使用了更多的内核,Python多处理速度较慢_Python_Numpy_Multiprocessing_Sparse Matrix - Fatal编程技术网

由于使用了更多的内核,Python多处理速度较慢

由于使用了更多的内核,Python多处理速度较慢,python,numpy,multiprocessing,sparse-matrix,Python,Numpy,Multiprocessing,Sparse Matrix,我正在使用Python多处理模块多次对(大而稀疏)矩阵进行对角化。我必须做上千次,所以决定在多处理中做,因为我有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()

我正在使用Python多处理模块多次对(大而稀疏)矩阵进行对角化。我必须做上千次,所以决定在多处理中做,因为我有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×8000稀疏矩阵进行对角化是速率决定步骤

当我没有使用多重处理时,这个过程运行得很好。然而,我现在实现多处理的速度与使用的内核数量成反比(!!)。我将非常感谢您在这方面的任何意见,因为我知道池通常会使您的流程(稍微)变慢,但不会降低这么多。我很困惑,因为scipy天生就没有实现多处理

例如。通常在一个内核中,10次对角化大约需要2秒。在24个核中(在上面的示例中为10个核!),需要约40秒

编辑:作为上下文,矩阵非常稀疏-8000 x 8000矩阵中只有48000个条目


编辑:已解决,但仍有剩余问题

我已经解决了这个问题,它非常有趣,我需要你的意见

问题如下:当scipy.sparse对大于某个阈值的矩阵进行对角化时,它会自动执行多线程(我用top进行了检查)。但是,与使用单芯机箱相比,这并没有显著提高速度

我用我自己的笔记本电脑检查了性能(双核,没什么特别的!),性能比24核输出要好(!),24核输出的失败次数稍多,但仍然如此。)并且意识到自动多线程并没有做任何事情,只是建立队列和阻塞多处理


因此,解决方案是使用操作系统将MKL和BLAS设置为单线程,然后设置为多线程,程序现在运行得非常好。我现在很好奇,为什么BLAS首先使用多线程,但根本不使用多线程——这可能是开发人员的问题,但可能还有另一个复杂的解决方案。谁知道呢

多处理意味着复制数据并在完成时将其聚合。这将产生影响。这不是神奇的空闲时间。序列化
wf
vf
会增加开销,但你正在并行化,所以你会得到一些回报。我不知道您是如何将数据导入分叉流程的,这也可能会减慢您的速度。如果你的内存不足,有10个矩阵副本,你必须交换,我预计会有巨大的性能损失(如你所见)。我不希望你的示例代码运行得那么慢,但魔鬼在细节中没有包括。嗨,谢谢你的回复!我写了一个只涉及矩阵对角化的伪代码。不幸的是,问题依然存在。eigsh代码一直是贪婪的罪魁祸首。我的第一个猜测是可能是GIL,但考虑到多进程是为了避免这个问题,我感到困惑……点头,GIL在这里不太可能是一个猜测,因为正如你所说,这正是多进程要防止的。在进程之间移动时,很可能是序列化/反序列化。正如Mad Physician所说,只有当您的计算非常昂贵,以至于执行多处理的成本超过移动数据的成本时,多处理才有价值(因此数据越大、越难处理,并行化的成本就越高)。也就是说,如果scipy为您尝试执行的计算在C中实现多线程,使用多处理是纯粹的损失;这只会让事情变得更糟,而且永远不会更好,因为多线程根本不需要在进程映像之间复制数据,而在C模块中编写的代码可以在GIL工作时释放GIL,因此,当您开始使用多线程时,每个进程都会启动自己的线程组(这些线程会相互竞争CPU),而且您拥有复制内容所需的所有开销。。