提问人:vitamin Cho 提问时间:11/17/2023 最后编辑:halfervitamin Cho 更新时间:11/17/2023 访问量:34
使用 joblib 比单线程循环慢
Using joblib is slower than single thread loop
问:
from tqdm import tqdm
from joblib import Parallel, delayed
import numpy as np
import time
def func(x,a,b,c):
"""x3+ax2+bx+c"""
return x**3+a*x**2+b*x+c
def func_prime(x,a,b):
"""3x2+2ax+b"""
return 3*x**2+2*a*x+b
def check(i):
a,b,c = i
if func_prime(-1/4, a,b) != -1/4:
return False
if func_prime(1/4,a,b) >=0:
return False
for i in range(-300,300):
if func(i-1, a,b,c)*func(i+1,a,b,c)<0:
return False
return a,b,c
def gen():
a=np.arange(-1, 1, 1/128)
b=np.arange(-1, 1, 1/128)
c=np.arange(-1, 1, 1/128)
for i_a in a:
for i_b in b:
for i_c in c:
yield i_a, i_b, i_c
# single thread. it spend 11 seconds.
result = set()
for i in tqdm(gen()):
result.update([check(i)])
# using joblib. it spend 313 seconds.
start_time = time.time()
_ = Parallel(n_jobs=10)(delayed(check)(i) for i in gen())
end_time = time.time()
print(end_time - start_time)
为了好玩,我试图解决一个数学测验,解决方案是“fx=x3-0.375x2-0.625x + 0”。
我的代码测试了所有值的组合,所以我认为并行编程可以加快速度。但事实并非如此,它比使用单个线程慢得多。
我的问题:
- 为什么多线程速度较慢?
- 如何比单线程更快地修复它?
- 提早停止。如果我找到解决方案,请尽快退出。我该如何实现?
答:
1赞
J_H
11/17/2023
#1
tl;dr:你在错误的地方迭代。
gen()
产生许多值(三元组),
这些序列化并向下发送到工作子进程。
def check(i):
a, b, c = i
...
for i in range(-300, 300):
首先,第二个是错误的标识符,它应该是.
从元组开始,然后切换到标量真是太奇怪了,
避免这样做。i
x
其次,循环可能会提前退出。
现在,如果我们通常进行 600 次迭代,
这可能是一种明智的亲子工作平衡。
但我感觉到我们花了很多钱
对这 3 元组进行时间序列化,发送它们
沿着管道,快速反序列化它们
在达到六百之前很久就提前退出。for
你已经嵌套了 a、b、c 循环和 10 个内核。
我建议父级只遍历值,
并让孩子担心迭代。
这样一来,您就花费了更大比例的 CPU 周期
在评估上比在序列化/反序列化上。a
b, c
func
单独问题:
if func_prime(-0.25, a, b) != -0.25:
通常不建议测试浮点数的完全相等性
(或者在这种情况下,不平等)。
比较时,
更喜欢计算是否小于一些小的 epsilon
(或者在本例中,大于 ε )。x == y
abs(x - y)
我们有一个特例,在这里, 2 的幂的倒数, 所以IEEE-754可以准确地表示 感兴趣的数量。 但总的来说,你应该发展 一些健康程度的偏执狂 关于 FP 舍入问题。
评论