作为Python初学者,我试图并行化函数的某些部分,作为优化例程的输入。该函数f返回给定向量b的对数似然,梯度和粗糙度。在此函数中,有三个独立的循环函数:loop_1
,loop_2
和loop_3
。
最有效的实施是什么?在三个并发进程中并行化三个循环函数或一次并行化一个循环?这怎么可以实现?使用多处理软件包时,我会得到一个' pickle'错误,因为我的嵌套循环函数不在通用命名空间中。
def f(b):
# Do something computational intensive on b
def calc(i, j):
return u, v, w
def loop_1():
for i in range(1:1000):
c, d, e = calc(i, 0)
for j in range(1:200):
f, g, h = calc(i, j)
return x, y, z
def loop_2():
# similar to loop_1
def loop_3():
# similar to loop_1
# Aggregate results from the three loops
return u, v, w
答案 0 :(得分:1)
有几种方法可以避免您收到的酸洗错误。
如果有意义,选项可以是异步的。有时它会使它变慢,有时会使它变慢。
在这种情况下,它看起来像下面的代码,当我忘记了事情时,我将它用作模板:
import asyncio
def f():
async def factorial(n):
f.p = 2
await asyncio.sleep(0.2)
return 1 if n < 2 else n * await factorial(n-1)
async def multiply(n, k):
await asyncio.sleep(0.2)
return sum(n for _ in range(k))
async def power(n, k):
await asyncio.sleep(0.2)
return await multiply(n, await power(n, k-1)) if k != 0 else 1
loop = asyncio.get_event_loop()
tasks = [asyncio.ensure_future(power(2, 5)),
asyncio.ensure_future(factorial(5))]
f.p = 0
ans = tuple(loop.run_until_complete(asyncio.gather(*tasks)))
print(f.p)
return ans
if __name__ == '__main__':
print(f())
Async和await是内置的关键字,如def,for,in等在python3.5中。
在函数中使用函数的另一个方法是使用线程代替。
from concurrent.futures import ThreadPoolExecutor
import time
def f():
def factorial(n):
f.p = 2
time.sleep(0.2)
return 1 if n < 2 else n*factorial(n-1)
def multiply(n, k):
time.sleep(0.2)
return sum(n for _ in range(k))
def power(n, k):
time.sleep(0.2)
return multiply(n, power(n, k-1)) if k != 0 else 1
def calculate(func, args):
return func(*args)
def calculate_star(args):
return calculate(*args)
pool = ThreadPoolExecutor()
tasks = [(power, (2, 5)), (factorial, (5, ))]
f.p = 0
result = list(pool.map(calculate_star, tasks))
print(f.p)
return result
if __name__ == '__main__':
print(f())
答案 1 :(得分:0)
您应该在流程池中启动您的功能。
import multiprocessing
pool = multiprocessing.Pool()
for i in range(3):
if i == 0:
pool.apply_async(loop_1)
elif i == 1:
pool.apply_async(loop_2)
if i == 2:
pool.apply_async(loop_3)
pool.close()
如果loop_1,loop_2和loop_3是相同功能的相同操作,你可以简单地调用loop_3三次。