gpt4 book ai didi

python - 为什么通过多处理库进行并行编程比通常的编程花费更长的时间?

转载 作者:行者123 更新时间:2023-12-01 01:49:54 28 4
gpt4 key购买 nike

编辑:我更改了三次函数并定义了我注意到此问题的实际优化问题。我还根据收到的评论更改了 block 的生成方式。

我正在尝试并行化一些代码以减少计算时间,但执行代码的并行化版本比非并行化版本花费的时间更长。我将展示一个简单的例子:

import multiprocessing as mp
import time
import numpy as np
from cvxpy import *
import functools
from sklearn.datasets import load_boston

boston = load_boston()
x = boston.data
y = boston.target

def lm_l_solver(x, y, lambda1):
n = x.shape[0]
m = x.shape[1]
lambda_param = Parameter(sign="positive")
beta_var = Variable(m)
lasso_penalization = lambda_param * norm(beta_var, 1)
lm_penalization = (1/n) * sum_squares(y - x * beta_var)
objective = Minimize(lm_penalization + lasso_penalization)
problem = Problem(objective)
# Solve optimization problem
beta_sol_matrix = np.zeros((len(lambda1), 1, m))
for i in range(len(lambda1)):
lambda_param.value = lambda1[i]
problem.solve(solver=CVXOPT)
beta_sol = np.asarray(np.row_stack([b.value for b in beta_var])).flatten()
beta_sol_matrix[i, :] = beta_sol
beta_sol_matrix[np.abs(beta_sol_matrix) < 1e-4] = 0
# Generate response
response = dict(solution=beta_sol_matrix, lambda1=lambda1)
return response

if __name__ == '__main__':
vector = np.arange(1, 100, 1)
start_time = time.time()
chunks = np.array_split(vector, mp.cpu_count())
pool = mp.Pool(processes=mp.cpu_count())
results = pool.map(functools.partial(lm_l_solver, x, y), chunks)
pool.close()
pool.join()
end_time_1 = time.time()
results2 = lm_l_solver(x, y, vector)
end_time_2 = time.time()
print('Parallel programming took {} seconds'.format(round(end_time_1-start_time, 2)))
print('Non parallel programming took {} seconds'.format(round(end_time_2 - end_time_1, 2)))

函数 lm_l_solver 接收数据矩阵 x、响应向量 y 和可能的 lambda 值向量,并求解每个 lambda 值的惩罚线性模型。

执行这段代码会生成以下输出:

Parallel programming took 5.28 seconds
Non parallel programming took 0.4 seconds

为什么会有这样的差异? “lm_l_solver”的并行化版本比非并行化版本花费了 13 倍的时间。我在这里做错了什么吗?

最佳答案

准确地重现有点困难,因为它取决于集群的配置。就我而言,无论我使用自己的 4 核 CPU 还是小型 24 核服务器,我都不会遇到更糟糕的并行行为。

无论如何,罪魁祸首是您的求解器 CVXOPT(使用 BLAS)已经是多线程的。通过尝试并行化您的代码,您正在与线性代数库竞争。为了证明我的观点,我强制 BLAS 仅使用一个线程。在这种情况下,多处理可以显示出一些优势:

$ python solver.py
Parallel programming took 2.0 seconds
Non parallel programming took 2.73 seconds

$ OMP_NUM_THREADS=1 python solver.py
Parallel programming took 0.57 seconds
Non parallel programming took 2.73 seconds

设置 OMP_NUM_THREADS=1 基本上会关闭 OpenMP 多线程,因此每个 Python 进程仍保持单线程;而BLAS也使用一个线程。

对于您的应用程序,您必须平衡线程数(OMP_NUM_THREADS)和进程数(例如 mp.Pool(processes=24))。

阅读引用资料

再现性

requirements.txt 使用 Python 2.7.5:

numpy
cvxpy==0.4.11
sklearn
cvxopt

关于python - 为什么通过多处理库进行并行编程比通常的编程花费更长的时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50832825/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com