Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.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_Scientific Computing - Fatal编程技术网

加速科学python程序

加速科学python程序,python,numpy,scientific-computing,Python,Numpy,Scientific Computing,我有以下python代码: def P(z, u0): x = np.inner(z, u0) tmp = x*u0 return (z - tmp) def powerA2(A, u0): x0 = np.random.rand(len(A)) for i in range(ITERATIONS): x0 = P(np.dot(A, x0), u0) x0 = x0 / np.linalg.norm(x0) r

我有以下python代码:

def P(z, u0):
    x = np.inner(z, u0)
    tmp = x*u0
    return (z - tmp)


def powerA2(A, u0):
    x0 = np.random.rand(len(A))
    for i in range(ITERATIONS):
        x0 = P(np.dot(A, x0), u0)
        x0 = x0 / np.linalg.norm(x0)
    return (np.inner(np.dot(A, x0), x0))
np
numpy

我对为大小为100000*100000的矩阵运行这段代码很感兴趣,但是这个程序似乎没有机会快速运行(我需要运行它很多次,大约10000次)

有没有可能在这里使用多线程之类的技巧?


还有什么可以加速它吗?

只需检查一下:您想对某个10^10的对象执行10^4操作。。。因此,即使您的操作是O(1),这仍然是10^14个操作,这是一个相当困难的问题(正如haraldkl在他的评论中指出的,这也消耗了大量内存),只是为了检查:您是要调用powerA2 10000次,还是10000次是迭代所需的值。如果是前者,您可以使用线程(或者更好的是,单独的进程)来获得一些并行化,但我不知道这是否足够;如果是后者,除非我遗漏了一个技巧,否则您的输入似乎不可并行化,因为每个循环迭代的输入都依赖于前一个循环的输出。可能有一种方法可以在GPU上实现这一点(我想至少有一种有效的方法可以实现规范化,这样它就可以通过使用矢量化快速完成大量工作)

编辑以回应评论:cpython(最常见的python实现)具有全局Interpeter锁(GIL);其他一些python实现(jython、ironpython)没有;每

请注意,可能会阻塞或长时间运行的操作,例如 I/O、图像处理和NumPy数字运算都发生在外部 吉尔。因此,只有在花费大量资源的多线程程序中才能实现 GIL内部的时间,解释CPython字节码,GIL 成为瓶颈

据我所知,使用NUMPY的线程可能是不可能的,但不是很困难的瓶颈,但是除非有一点数学缺失,否则你的问题看起来很难转换成线程。

你可以考虑使用。编译以下代码(

norm.py
):

与:

产生以下加速:

$ python -m timeit -s 'import numpy as np; A = np.random.rand(100, 100); B = np.random.random(100); import norm' 'norm.powerA2(A, B)'
100 loops, best of 3: 3.1 msec per loop
$ pythran norm.py -O3 -march=native
$ python -m timeit -s 'import numpy as np; A = np.random.rand(100, 100); B = np.random.random(100); import norm' 'norm.powerA2(A, B)'
1000 loops, best of 3: 937 usec per loop

通过以下方式重新定义函数,我比未填充的serge sans paille版本提高了10%:

def P0(z, u0):
    x = np.inner(z, u0)
    x *= u0
    return (z - x)

def norm0(x):
    return np.sqrt(np.sum(x*x))

def powerA20(A, u0):
    ITERATIONS = 100
    x0 = np.random.random(len(A))
    for i in range(ITERATIONS):
        x0 = P0(np.dot(A, x0), u0)
        x0 /= norm0(x0)
    return (np.inner(np.dot(A, x0), x0))
*=u0
而不是
x=x*u0
这样做可以避免不必要地复制RAM中的变量,从而稍微加快程序的速度。
此外,在这种情况下,您不需要
abs
。最后,
x*x
x**2

100000^2 64位real的内存量略快。这对你来说不是问题吗?在我看来,加快这一进程的第一步是转而使用编译语言。我知道numpy是在幕后做这件事的,但我猜,通过在编译语言中本机实现这一点,并调用该例程(而不是Python),可以避免很多内存访问。这会是一种改进吗?这个模块是复杂程序的一部分,将其转换为编译语言需要几天的时间见serge sans paille答案,我不知道pythran的情况,但他展示的基本上是3的加速。当然,这取决于问题,但我想对于更大的问题,这变得更加重要。正如我所说的,您可以考虑用编译语言实现它并从Python调用它,虽然这有点复杂,但应用程序的其余部分可能保持不变。这个Pythran的建议基本上让你实现了自动化。仅仅使用numpy,我所能得到的最大加速是1.8倍。您可以将
linalg.norm
行从
ITERATIONS
循环中去掉,以获得适当的加速,但我想这是为了稳定性?您可以使用
x0/=math.sqrt(np.dot(x0,x0))
而不是
x0=x0/np.linalg.norm(x0)
来加速该队列。使用
out=
参数并在适当的位置执行一些操作,速度会快一点。令人惊讶的是(对我来说)
np.einsum
在任何地方都没有帮助
np.internal
np.dot
非常快。我听说python有解释器锁,那么,多线程可以在python中工作吗?谢谢!它还会运行(更大的)矩阵吗?它将数据存储为平面阵列,并尽可能避免临时性,所以只要矩阵适合内存,我会说是的。
$ python -m timeit -s 'import numpy as np; A = np.random.rand(100, 100); B = np.random.random(100); import norm' 'norm.powerA2(A, B)'
100 loops, best of 3: 3.1 msec per loop
$ pythran norm.py -O3 -march=native
$ python -m timeit -s 'import numpy as np; A = np.random.rand(100, 100); B = np.random.random(100); import norm' 'norm.powerA2(A, B)'
1000 loops, best of 3: 937 usec per loop
def P0(z, u0):
    x = np.inner(z, u0)
    x *= u0
    return (z - x)

def norm0(x):
    return np.sqrt(np.sum(x*x))

def powerA20(A, u0):
    ITERATIONS = 100
    x0 = np.random.random(len(A))
    for i in range(ITERATIONS):
        x0 = P0(np.dot(A, x0), u0)
        x0 /= norm0(x0)
    return (np.inner(np.dot(A, x0), x0))