Python 3:多重矩阵的并行对角化

Python 3:多重矩阵的并行对角化,python,multithreading,matrix,Python,Multithreading,Matrix,我试图改进我的一些代码的性能,它首先根据两个索引构造一个4x4矩阵,对角化该矩阵,然后将每个矩阵的每个对角化的特征向量存储在一个四维数组中。目前,我只是串行地遍历所有索引,然后将特征向量存储在四维数组中的相应位置。现在,我想知道是否有可能通过使用线程或类似的方法来将其并行化,这样每个线程将对角化一个矩阵,然后将其存储在它的位置。我的问题是,我这样做的局限性是什么?当不同的线程想要写入生成的4-dim时,我会遇到问题吗。同时使用数组,我是否必须使用锁来防止这种情况?我很抱歉,如果这个问题是琐碎的,

我试图改进我的一些代码的性能,它首先根据两个索引构造一个4x4矩阵,对角化该矩阵,然后将每个矩阵的每个对角化的特征向量存储在一个四维数组中。目前,我只是串行地遍历所有索引,然后将特征向量存储在四维数组中的相应位置。现在,我想知道是否有可能通过使用线程或类似的方法来将其并行化,这样每个线程将对角化一个矩阵,然后将其存储在它的位置。我的问题是,我这样做的局限性是什么?当不同的线程想要写入生成的4-dim时,我会遇到问题吗。同时使用数组,我是否必须使用锁来防止这种情况?我很抱歉,如果这个问题是琐碎的,但通过搜索,我无法找到任何相关的东西,我对线程的知识非常有限。一个最起码的例子是

from numpy.linalg import eigh as eigh2
from scipy import *

spectrum = zeros([L//2,L//2,4,4],complex)
for i in range(0,L//2):
    for j in range(0,L//2):
        k = [-(2 * i*2*pi/L),-(2 * j*2*pi/L)]
        H = ones([4,4],complex)
        energies, states = eigh2(H)
        spectrum[i,j,:,:] = states
注意,为了简洁起见,我将依赖于k构造矩阵的函数替换为一些常数矩阵


我真的非常感谢任何关于如何实现一些并行化的帮助或参考资料。线程化是提高性能的现实方法吗?

简单的回答是,是的,您可能需要锁,但如果您可以重新组织问题,那么这可能比锁定要好得多

长答案有点复杂,特别是因为我不知道你已经知道多少

一般来说,线程在CPython中对CPU绑定代码没有多大好处,因为它会阻止任何线程在Python中解释一行(实际上是字节码),如果另一个线程在这样做的话。然而,NumPy有专门在某些地方释放GIL的代码,以允许线程更好地工作,因此,如果您的CPU受限于低级NumPy算法,那么线程实际上可以工作。文档并不总是清楚哪些函数可以这样做,哪些不可以,所以您可能需要自己测试一下,看看并行化是否有帮助。(一种快速而肮脏的方法是,破解一个只进行计算而不将计算存储在任何地方的代码版本,跨N个线程运行,然后查看在执行时有多少内核处于繁忙状态。)

现在,一般来说,在CPython中,某些类型的操作不需要锁,包括简单类型的
\uuuu setitem\uuuu
,但这是因为相同的GIL,所以在这里对您没有帮助。如果有多个操作都试图写入同一个数组,则需要在该数组周围设置锁

但也许有更好的办法解决这个问题。如果可以找到一种方法将数组划分为更小的数组,并且在任何给定的时间只修改其中一个数组,那么就不需要任何锁。或者,如果您可以让线程返回更小的数组,这些数组可以由单个主线程组装到最终答案中,而不是一开始就就地工作,那么这也可以工作

但在你开始之前…在某些情况下,NumPy(或者,更确切地说,它正在使用的一个库)已经在为你自动并行化了,或者如果你以不同的方式构建它的话,它可能会自动并行化。或者它可以是SIMD矢量化的方式,实际上比线程化提供更多的加速,而线程化最终可能会崩溃。等等

因此,在尝试任何操作之前,请确保安装了一个经过适当优化的NumPy以及所有可选的prereq。然后确保它只使用一个核心。然后构建一个测试框架,以便比较不同的实现。然后你可以尝试每一种基于锁的、非共享的、非变异的算法,看看并行性是否比额外的东西更有用