使用多处理不会减少计算时间

时间:2018-06-06 13:56:51

标签: python multiprocessing

一个问题。 使用multiprocessing是为了获得更快的代码。 但是在使用以下框架之后,获取输出所花费的时间与普通代码相同或更多。

import multiprocessing

def code() :
    my code

if __name__ == '__main__' :
    p = multiprocessing.Process(target = code)
    p.start()
    p.join()

由于是2台处理器笔记本电脑,运行此代码后程序要我导入数据两次。 问题是以这种方式没有任何意义的时间。只要普通代码没有并行性,我就会遇到很长时间。

import numpy as np
from scipy.integrate import odeint
from math import *
from scipy.integrate import quad
import pandas as pd
import os
import warnings
warnings.filterwarnings("ignore")
#you need add the following 3 lines
from multiprocessing import Pool
from multiprocessing import Process
import multiprocessing

print("Model 4, Equation 11")
print("")
###################### STEP NUMBER #######################
N = int(input("PLEASE ENTER NUMBER OF STEP WALKS: "))  # Step walk by user
dec=int(input("NUMBER OF DECIMAL PLACES OF OUTPUTS (RECOMENDED 10-15)?"))
print("")
print("PLEASE WAIT, METROPOLIS HASTINGS IS RUNNING ... ")
print("")

def FIT():

##########################################################

    od0o  = np.zeros((N,))
    od0o[0]=0.72        
    od0n = np.zeros((N,))

    Mo  = np.zeros((N,))
    Mo[0]= 0         
    Mn = np.zeros((N,))

    co  = np.zeros((N,))
    co[0]= 0.84         
    cn = np.zeros((N,))

    bo  = np.zeros((N,))
    bo[0]= 0.02         
    bn = np.zeros((N,))

    H0o  = np.zeros((N,))
    H0o[0]= 70      
    H0n = np.zeros((N,))

    Orco  = np.zeros((N,))
    Orco[0]= 0.0003       
    Orcn = np.zeros((N,))

    temp=1e10    # a big number

##########################################################
    CovCMB=[[3.182,18.253,-1.429],              
           [18.253,11887.879,-193.808],
           [-1.429,-193.808,4.556]]  # CMB DATA



##########################################################
    def OD_H(U,z,c,b,Orc):
        od, H = U
        Omegai = 3 * b * ((1- od - 2*(Orc)**0.5) + (1- od - 2*(Orc)**0.5)**2/(1-2*(Orc)**0.5)) #equation 10
        div1=np.divide((c**2-od),(1+z),where=(1+z)!=0) 
        div2=np.divide(H ,(1+z),where=(1+z)!=0)
        dMdt = (div1)*(6*od+6-9*(od/c**2)+ Omegai)*(1+c**2+od*(1-3/c**2))**(-1)
        dHdt =       (div2)*(6*od+6-9*(od/c**2)+ Omegai)*(1+c**2+od*(1-3/c**2))**(-1)
        return [dMdt, dHdt]

    def solution(H0,z1,z,od0,c,b,Orc):
        U = odeint(OD_H,[od0,H0],[z1,z], args=(c,b,Orc))[-1]
        od, H = U                    
        return H    

##########################################################
    def DMCMB1(H0,z1,z,od0,c,b,Orc):
        dm = 1090 * 1/solution(H0,z1,z,od0,c,b,Orc)
        return dm
    def R1(H0,z1,z,od0,c,b,Orc):
        #r=sqrt(Om)*(70/299000)*rszstar(z,Om,Od)
        r = sqrt(1-od0-2*(Orc)**0.5)*DMCMB1(H0,z1,z,od0,c,b,Orc)
        return r
    def lA1(H0,z1,z,od0,c,b,Orc):
        la=((3.14*299000/H0)*DMCMB1(H0,z1,z,od0,c,b,Orc))/(153)
        return la

    def CMBMATRIX1(H0,z1,z,od0,c,b,Orc,M):
        hmCMB1=[lA1(H0,z1,z,od0,c,b,Orc)-301.57, R1(H0,z1,z,od0,c,b,Orc)-1.7382+M, 0.0222-0.02262]
        vmCMB1=[[lA1(H0,z1,z,od0,c,b,Orc)-301.57], [R1(H0,z1,z,od0,c,b,Orc)-1.7382], [0.0222-0.02262]]
        fmCMB1=np.dot(hmCMB1,CovCMB)
        smCMB1=np.dot(fmCMB1,vmCMB1)[0]
        return smCMB1

######################################################   
    def TOTAL(H0, od0, c, b,Orc, M)  :
        total =  CMBMATRIX1(H0,0,1090,od0,c,b,Orc,M)
        return total
######################################################
################## MCMC - MH #########################                 
    highest=0
    pat='C:/Users/21/Desktop/MHT/Models/outputs'
    file_path = os.path.join(pat,'Model3.txt')
    file_path2 = os.path.join(pat,'Model3min.txt')
    with open(file_path, 'w') as f:    # DATA WILL BE SAVED IN THIS FILE, PLEASE BECAREFUL TO CHANGE THE NAME IN EACH RUN TO AVOIDE REWRITING.
        with open(file_path2, 'w') as d:
            for i in range (1,N):
                num = 0
                R = np.random.uniform(0,1)    
                while True:
                      num += 1
                      od0n[i] = od0o[i-1] + 0.001 * np.random.normal()
                      H0n[i] = H0o[i-1] + 0.01 * np.random.normal()
                      bn[i] = bo[i-1] + 0.001 * np.random.normal()
                      cn[i] = co[i-1] + 0.001 * np.random.normal()
                      Mn[i] = Mo[i-1] + 0.01 * np.random.normal()
                      Orcn[i] = Orco[i-1] + 0.00001 * np.random.normal()

                      L = np.exp(-0.5 * (TOTAL(H0n[i], od0n[i], cn[i], bn[i],Orcn[i], Mn[i]) - TOTAL(H0o[i-1], od0o[i-1], co[i-1], bo[i-1],Orco[i-1], Mo[i-1])))    # L = exp(-( x^2 )/2)
                      LL=min(1,max(L,0))


                      if LL>R:          
                         od0o[i]= od0n[i]
                         H0o[i] = H0n[i]
                         bo[i] = bn[i]
                         co[i] = cn[i]
                         Mo[i] = Mn[i]
                         Orco[i] = Orcn[i]
                         chi = TOTAL(H0o[i], od0o[i], co[i], bo[i],Orco[i], Mo[i])
                      else:           
                          od0o[i]= od0o[i-1]
                          H0o[i] = H0o[i-1]
                          bo[i] = bo[i-1]
                          co[i] = co[i-1]
                          Mo[i] = Mo[i-1]
                          Orco[i] = Orco[i-1]
                          chi = TOTAL(H0o[i], od0o[i], co[i], bo[i],Orco[i], Mo[i])


                      if (Mo[i]>0 and 0<bo[i]<0.09 and Orco[i]>0)  or num>100:               # constraining the value to stay in positive area
                         highest = max(num, highest)
                         break

                f.write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\n".format(round(chi,dec),'   ',round(H0o[i],dec),'  ',round(od0o[i],dec),'  ',
                                                                                          round(co[i],dec),'    ',round(bo[i],dec),'  ',
                                                                                                     round(Orco[i],dec),' ',round(Mo[i],dec)))

                if chi<temp:        
                       temp=chi
                       aa = H0o[i]
                       bb = od0o[i]
                       cc = co[i]
                       dd = bo[i]
                       ee = Mo[i]
                       ff=Orco[i]
                       Om=1-2*sqrt(Orco[i])-od0o[i]
        # minimum of chi and its parameters
            d.write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12},\t{13}\t{14}\n".format(round(temp,dec), "H =", round(aa,dec), "Orc=",
                                                                                                      round(ff,dec), "OD =",round(bb,dec),"c =",
                                                                                                      round(cc,dec),"b =", round(dd,dec),
                                                                                                     "M =",round(ee,dec),"Om =",round(Om,dec)))
            print(round(temp,dec), "H =", round(aa,dec), "Orc=",round(ff,dec), "OD =",round(bb,dec),"c =", round(cc,dec),"b =", round(dd,dec), "M =",round(ee,dec),"Om =",round(Om,dec)) 
    #print(highest)
    print("")

#test = input("Press the enter to exit...")
#print(test)    
if __name__ == '__main__':
    p = multiprocessing.Process(target=FIT)
    p.start()
    p.join()

2 个答案:

答案 0 :(得分:1)

我认为你错过了multiprocessing的主要概念。它不会更快地运行你的代码,只是让你在另一个进程中运行一些东西来绕过GIL(https://wiki.python.org/moin/GlobalInterpreterLock)。

它可用于并行计算不同输入值的某些函数,例如docs

中的此示例
from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    p = Pool(5)
    print(p.map(f, [1, 2, 3]))

这导致在不同进程中计算f,并且每个进程都返回单独的值

答案 1 :(得分:0)

您只创建一个进程,而您的所有其他逻辑都是顺序的,这就是性能没有变化的原因,因为所有代码都会按顺序运行。 有两种不同的方案可以使用多处理

  1. 完全独立的功能
    如果您具有完全独立的功能并且顺序执行它们没有限制,您可以以这种方式并行执行它们这些功能都不是将不得不等待彼此 一个很好的类比就是阅读新闻报纸,在这里吃早餐不需要按顺序进行,所以我们可以同时进行。

  2. 为不同的输入执行相同的功能
    如果您为不同的输入重复执行某个功能,那么您可以一次为多个输入执行该功能的多个实例 比喻一下单票计数器 然后考虑多个票证计数器相同功能的多个实例。



  3. 在代码中找到这些场景,然后尝试并行化这些功能。
    希望它有所帮助。