【发布时间】:2019-01-29 05:41:38
【问题描述】:
我一直认为 python 列表理解并没有隐含地利用多处理,并且阅读堆栈上的问题(例如this one)也给了我同样的印象。但是,这是我的小实验:
import numpy as np
import time
# some arbitrary data
n = 1000
p = 5
X = np.block([[np.eye(p)], [np.zeros((n-p, p))]])
y = np.sum(X, axis=1) + np.random.normal(0, 1, (n, ))
n_loop = 100000
# run linear regression using direct matrix algebra
def in_sample_error_algebra(X, y):
beta_hat = np.linalg.inv(X.transpose()@X)@(X.transpose()@y)
y_hat = X@beta_hat
error = metrics.mean_squared_error(y, y_hat)
return error
start = time.time()
errors = [in_sample_error_algebra(X, y) for _ in range(n_loop)]
print('run time =', round(time.time() - start, 2), 'seconds')
运行时间 = 19.68 秒
当这段代码运行时,我的 CPU 的所有 6 个(物理)内核都达到了 100%
更神奇的是,当我从列表推导式更改为 for 循环时,同样的事情发生了。我认为使用.append,必须按顺序完成。见下文:
start = time.time()
errors = []
for _ in range(n_loop):
errors.append(in_sample_error_algebra(X, y))
print('run time =', round(time.time() - start, 2), 'seconds')
运行时间 = 21.29 秒
有什么理论吗?
Python 3.7.2, numpy 1.15.4
【问题讨论】:
-
我很确定那是
numpy使用线程... -
多线程甚至可以帮助python中的CPU绑定程序吗?我以为有 GIL。
-
许多
numpy计算不受 GIL、IIRC 的约束。 -
numpyc代码的各个块都有no gil包装器。
标签: python-3.x numpy parallel-processing python-3.7