Python 3.x python-3并行化我的函数问题

Python 3.x python-3并行化我的函数问题,python-3.x,numpy,parallel-processing,python-multiprocessing,Python 3.x,Numpy,Parallel Processing,Python Multiprocessing,我正在使用python-3.x,我想通过使用多处理并行化我的函数来加快代码的速度,我应用了多处理,但由于某种原因,它可能不起作用,我不确定问题出在哪里 下面是我所做的一个小例子。 如有任何建议,我们将不胜感激 import numpy as np import math import multiprocessing as mp lower_bound = -500 upper_bound =500 dimension =1000 Base_Value = 10 Popula_size = 3

我正在使用python-3.x,我想通过使用多处理并行化我的函数来加快代码的速度,我应用了多处理,但由于某种原因,它可能不起作用,我不确定问题出在哪里

下面是我所做的一个小例子。 如有任何建议,我们将不胜感激

import numpy as np
import math
import multiprocessing as mp

lower_bound = -500
upper_bound =500 
dimension =1000
Base_Value = 10
Popula_size = 3000
MinResolution = 8

population_in = np.random.choice ( np.linspace ( lower_bound , upper_bound , Base_Value ** MinResolution ) , size = ( Popula_size , dimension ) , replace = True )
resolution = np.random.randint(1, 8, size = (1, dimension))

def Discretiz(lower_bound, upper_bound, DiscPopulation, resolution):
        
    pop_size = int(len(DiscPopulation))
    the_new_population = np.zeros ((pop_size, dimension))
    for i in range (pop_size) :
        for ii in range (dimension):          
            decimal = int(np.round((DiscPopulation[i][ii] - lower_bound) / ((upper_bound-lower_bound)/(math.pow(Base_Value,resolution[:,ii])-1))))
            the_new_population[i, ii]  = (lower_bound + decimal *  ((upper_bound-lower_bound)/(math.pow(Base_Value,resolution[:,ii])-1)))
    return the_new_population


# without_parallelizing
# the_new_population = Discretiz(lower_bound, upper_bound, population_in, resolution)


# wit_parallelizing
pool = mp.Pool(mp.cpu_count())
the_new_population = [pool.apply(Discretiz, args=(lower_bound, upper_bound, population_in, resolution))]


print (the_new_population)

我现在修复了代码,但仍然没有比旧代码快。它需要更多的时间。不知道为什么? 不并行化:25.831339597702026秒 并行化:44.12706518173218秒

import numpy as np
import math
import multiprocessing as mp
import time

from multiprocessing import Process, Value, Array, Manager, Pool, cpu_count
import time

lower_bound = -500
upper_bound =500 
dimension =1000
Base_Value = 10
Popula_size = 2000
MinResolution = 8

population_in = np.random.choice ( np.linspace ( lower_bound , upper_bound , Base_Value ** MinResolution ) , size = ( Popula_size , dimension ) , replace = True )
resolution = np.random.randint(1, 8, size = (1, dimension))

start_time = time.time()
def Discretiz1(DiscPopulation, resolution):
# def Discretiz1(DiscPopulation):
    DiscPopulation = np.reshape(DiscPopulation, (Popula_size, dimension))
    resolution = np.reshape(resolution, (1,dimension))
    the_new_population = np.zeros ((Popula_size, dimension))
    for i in range (Popula_size) :
        for ii in range (dimension):          
            decimal = int(np.round((DiscPopulation[i][ii] - lower_bound) / ((upper_bound-lower_bound)/(math.pow(Base_Value,resolution[:,ii])-1))))
            the_new_population[i, ii]  = (lower_bound + decimal *  ((upper_bound-lower_bound)/(math.pow(Base_Value,resolution[:,ii])-1)))
    # print(the_new_population)

if __name__ == '__main__':

    num_cores = cpu_count()
    Pool(processes=num_cores)
    population_in = np.reshape(population_in, (1,Popula_size * dimension))[0]
    resolution = np.reshape(resolution, (1,dimension))[0]
    arr1 = Array('d', population_in)
    arr2 = Array('i', resolution)
    
    start_time = time.time()
    p = Process(target=Discretiz1, args=(arr1, arr2))
    p.start()
    p.join()
    print('--- %s seconds ---'%(time.time() - start_time))
    
print("--- %s seconds ---3" % (time.time() - start_time))
这是旧版本或未并行化版本:

import numpy as np
import math
import multiprocessing as mp
import time

from multiprocessing import Process, Value, Array, Manager, Pool, cpu_count
import time

lower_bound = -500
upper_bound =500 
dimension =1000
Base_Value = 10
Popula_size = 2000
MinResolution = 8

population_in = np.random.choice ( np.linspace ( lower_bound , upper_bound , Base_Value ** MinResolution ) , size = ( Popula_size , dimension ) , replace = True )
resolution = np.random.randint(1, 8, size = (1, dimension))

start_time = time.time()
def Discretiz(lower_bound, upper_bound, DiscPopulation, resolution):
        
    pop_size = int(len(DiscPopulation))
    the_new_population = np.zeros ((pop_size, dimension))
    for i in range (pop_size) :
        for ii in range (dimension):          
            decimal = int(np.round((DiscPopulation[i][ii] - lower_bound) / ((upper_bound-lower_bound)/(math.pow(Base_Value,resolution[:,ii])-1))))
            the_new_population[i, ii]  = (lower_bound + decimal *  ((upper_bound-lower_bound)/(math.pow(Base_Value,resolution[:,ii])-1)))
    return the_new_population

# without_parallelizing
the_new_population = Discretiz(lower_bound, upper_bound, population_in, resolution)

print("--- %s seconds ---" % (time.time() - start_time))
与:

您可以制作一个二维数组
(大众大小、尺寸)
形状。这将作为
discpropulation
传递

resolution = np.random.randint(1, 8, size = (1, dimension))
双迭代函数可以替换为在整个阵列上运行而无需缓慢迭代的函数:

def Discretiz(lower_bound, upper_bound, DiscPopulation, resolution):
    pop_size = DiscPopulation[0]  # no need for the 'int'
    num = DiscPopulation - lower_bound
    divisor = (upper_bound-lower_bound)/(Base_value**resolution-1)
    decimal = num/divisor
    # this divide does (pop,dimension)/(1,dimension); ok by broadcasting)
    decimal = np.round(decimal)  # no need for int
    the_new_population = lower_bound + decimal * divisor
    return the_new_population

我在这里写的。它在语法上是正确的,但我没有尝试运行它。

numpy
可以在整个数组上执行相同的操作时,为什么要使用
math
函数
math.power
需要标量输入,迫使您对循环使用慢速双精度
。在加入多处理潮流之前,您应该最大限度地使用
numpy
。@hpaulj感谢您的帮助,但是我如何将numpy能力应用到我的工作中,比如数学能力
math.pow(基值,分辨率[:,ii])-1) 
例如,您是否可以添加不起作用的内容以及如何确定这些内容?@atru您是否可以查看我的答案我仔细查看了您的代码:您需要为自己指定您正试图并行化的内容以及如何并行化。它可能像并行和共享数组一样简单,但我需要刷新更多详细信息。这是我有史以来最好的答案,你知道吗,从这里我更改了大部分代码,因为大部分
for循环
都被删除了。编程就是我们思考的方式。再次感谢你,我从中学到了很多:)
def Discretiz(lower_bound, upper_bound, DiscPopulation, resolution):
    pop_size = DiscPopulation[0]  # no need for the 'int'
    num = DiscPopulation - lower_bound
    divisor = (upper_bound-lower_bound)/(Base_value**resolution-1)
    decimal = num/divisor
    # this divide does (pop,dimension)/(1,dimension); ok by broadcasting)
    decimal = np.round(decimal)  # no need for int
    the_new_population = lower_bound + decimal * divisor
    return the_new_population