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

python的多处理模块是加速大型数值计算的正确方法吗?

python的多处理模块是加速大型数值计算的正确方法吗?,python,parallel-processing,multiprocessing,Python,Parallel Processing,Multiprocessing,我在使用FORTRAN进行数值计算和OpenMP并行化方面有很强的背景,我发现在许多问题上使用它很容易。我改用PYTHON,因为它开发起来更有趣(至少对我来说),但用于数字任务的并行化似乎比使用OpenMP要乏味得多。我经常感兴趣的是将大型(数十GB)数据集加载到主存,并在主存中只包含一个数据副本(共享数据)的同时并行操作它。我开始为此使用PYTHON模块多处理,并给出了一个通用示例: #test cases #python parallel_python_example.py 1000

我在使用FORTRAN进行数值计算和OpenMP并行化方面有很强的背景,我发现在许多问题上使用它很容易。我改用PYTHON,因为它开发起来更有趣(至少对我来说),但用于数字任务的并行化似乎比使用OpenMP要乏味得多。我经常感兴趣的是将大型(数十GB)数据集加载到主存,并在主存中只包含一个数据副本(共享数据)的同时并行操作它。我开始为此使用PYTHON模块多处理,并给出了一个通用示例:

#test cases    
#python parallel_python_example.py 1000 1000
#python parallel_python_example.py 10000 50

import sys
import numpy as np
import time
import multiprocessing
import operator

n_dim = int(sys.argv[1])
n_vec = int(sys.argv[2])

#class which contains large dataset and computationally heavy routine
class compute:
    def __init__(self,n_dim,n_vec):
        self.large_matrix=np.random.rand(n_dim,n_dim)#define large random matrix
        self.many_vectors=np.random.rand(n_vec,n_dim)#define many random vectors which are organized in a matrix
    def dot(self,a,b):#dont use numpy to run on single core only!!
        return sum(p*q for p,q in zip(a,b))
    def __call__(self,ii):# use __call__ as computation such that it can be handled by multiprocessing (pickle)
        vector = self.dot(self.large_matrix,self.many_vectors[ii,:])#compute product of one of the vectors and the matrix
        return self.dot(vector,vector)# return "length" of the result vector

#initialize data
comp = compute(n_dim,n_vec)

#single core
tt=time.time()
result = [comp(ii) for ii in range(n_vec)]
time_single = time.time()-tt
print "Time:",time_single

#multi core
for prc in [1,2,4,10]:#the 20 case is there to check that the large_matrix is only once in the main memory
  tt=time.time()
  pool = multiprocessing.Pool(processes=prc)
  result = pool.map(comp,range(n_vec))
  pool.terminate()
  time_multi = time.time()-tt  
print "Time using %2i processes. Time: %10.5f, Speedup:%10.5f" % (prc,time_multi,time_single/time_multi)
我在我的机器上运行了两个测试用例(使用Fedora18的64位Linux),结果如下:

andre@lot:python>python parallel_python_example.py 10000 50
Time: 10.3667809963
Time using  1 processes. Time:   15.75869, Speedup:   0.65785
Time using  2 processes. Time:   11.62338, Speedup:   0.89189
Time using  4 processes. Time:   15.13109, Speedup:   0.68513
Time using 10 processes. Time:   31.31193, Speedup:   0.33108
andre@lot:python>python parallel_python_example.py 1000 1000
Time: 4.9363951683
Time using  1 processes. Time:    5.14456, Speedup:   0.95954
Time using  2 processes. Time:    2.81755, Speedup:   1.75201
Time using  4 processes. Time:    1.64475, Speedup:   3.00131
Time using 10 processes. Time:    1.60147, Speedup:   3.08242

我的问题是,我是否误用了这里的多处理模块?或者PYTHON就是这样(即不要在PYTHON中并行化,而是完全依赖于numpy的优化)

用Python进行数字运算。。。你可能应该了解一下。它是Python和C之间的中间语言。它与numpy紧密连接,并支持使用openMP作为后端并行化。

虽然您的问题(标题中)没有一般性的答案,我认为可以说,
多处理
本身并不是Python中出色的数字处理性能的关键

然而,原则上,Python(+第三方模块)对于数字运算来说是非常棒的。找到合适的工具,你会感到惊讶。我敢肯定,在大多数情况下,与在Fortran中手动执行所有操作之前相比,通过编写(少得多!)的代码,您将获得更好的性能。你只需要使用正确的工具和方法。这是一个广泛的话题。您可能会感兴趣的一些随机事件:

  • 您可以自己使用Intel MKL和OpenMP编译numpy和scipy(或者您设备中的系统管理员已经这样做了)。这样,许多线性代数运算将自动使用多个线程,并从机器中获得最佳效果。这简直太棒了,到目前为止可能被低估了。把你的手放在正确编译的numpy和scipy上

  • 多处理
    应被理解为管理多个或多或少独立的过程的有用工具。这些过程之间的通信必须明确编程。通信主要通过管道进行。相互交谈的过程大部分时间都在交谈,而不是计算数字。因此,
    多处理
    最好用于输入和输出数据的传输时间小于计算时间的情况。还有一些技巧,例如,您可以利用Linux的
    fork()
    行为,在多个
    多处理
    进程之间共享大量内存(只读!),而不必通过管道传递这些数据。你可能想看看

  • Cython已经提到过,您可以在特殊情况下使用它,并用编译后的代码替换Python程序中性能关键的代码部分

我没有评论你的代码的细节,因为(a)它不是很可读(请在编写Python代码时习惯:-)和(b)我认为,特别是关于数字运算,这取决于问题的正确解决方案。您已经在您的基准测试中观察到了我上面概述的内容:在
多处理的上下文中,关注通信开销尤其重要


一般来说,您应该始终尝试从Python内部找到一种方法来控制编译后的代码,以便为您完成繁重的工作。Numpy和SciPy为此提供了很好的接口。

从您提供的测试结果来看,您似乎在双核机器上运行了测试。我有其中一个,运行了您的测试代码,得到了类似的结果。这些结果表明,运行比数值应用程序核更多的进程并没有什么好处,这些数值应用程序可以进行并行计算

在我的双核机器上,大约20%的CPU被简单地用于保持我的环境运行,因此当我看到运行两个进程的1.8改进时,我确信所有可用的周期都被用于我的工作。基本上,对于并行数值计算来说,核越多越好,因为这提高了可用于计算的计算机的百分比


其他海报完全正确地指出了Numpy、Scipy、Cython等。基本上,你首先需要让你的计算使用尽可能少的周期,然后以某种形式使用多重处理来找到更多的周期来应用于你的问题。

数值计算可以在线程上运行。这就是第二个示例所显示的,但是在第一个例子中(带有一些乘法的巨大矩阵),这似乎是一个巨大的开销——我不记得在OpenMP和FORTAN@JakobBowyer:谈论Python
threading
模块?那么,从GIL开始,CPU受限的应用程序将不会从Python线程中获益。然而,本机线程非常棒,但它必须得到底层库的支持。@Jan PhilipGehrcke:不正确。矢量化numpy计算,您无论如何都应该使用它来提高性能,这可能会释放GIL,也就是说,即使使用
线程
模块,CPU绑定的应用程序也可以获得性能。@J.F.Sebastian:我试图用“这必须由底层库支持”来说明这一点,但这是一个非常特殊的情况。我认为让人们意识到这样一个事实是很重要的,一般来说,当应用程序是CPU受限的时候,Python的线程处理是没有帮助的。好的,我将研究一下这个问题。感谢您对我的问题的详细回答!既然你也提到了cython,我肯定会仔细研究一下,还有其他一些问题,我会把它作为我问题的答案。嗯,看起来很好