在 Python 中并行化 for 循环
Parallelizing for loop in Python
我编写了一个运行速度非常慢的神经网络,所以我希望通过并行化某个循环来加快它的速度。
我不确定 GIL 的实现和工作方式,以及它是否与我相关。
代码如下所示:
class net():
def train(inputs)
...
for tset in batch:
self.backprop(tset, learn_rate)
def backprop(inputs):
...
for c, w in zip(n.inconnections, range(len(n.inconnections))):
c.current_error += n.current_error * n.inconnectionweights[w]
n.icweightupdates[w] += - learn_rate * n.current_error * c.activation
n.biasupdate += -learn_rate * n.current_error
train()
中的循环是我想要并行化的循环,因为 batch
包含一组可独立处理的训练样本 (20)。
Python 线程不会使它更快,因为 GIL。相反,您可以尝试流程:
import multiprocessing
class net():
def train(inputs)
...
with multiprocessing.Pool() as p:
biasupdates = p.map(lambda tset: self.backprop(tset, learn_rate), batch)
n.biasupdate += sum(biasupdates)
def backprop(inputs):
...
for c, w in zip(n.inconnections, range(len(n.inconnections))):
c.current_error += n.current_error * n.inconnectionweights[w]
n.icweightupdates[w] += - learn_rate * n.current_error * c.activation
return -learn_rate * n.current_error
当“AGILE”布道团的鼓声越来越响的时候,
永远不要在知道这样做有意义之前开始编码:
为什么?
您确实可以花费无限多的时间来编写一个甚至没有意义的东西,而 在适当的系统工程上花费合理的时间将帮助您确定哪些步骤是合理的,哪些是不合理的。
那么,让我们从一个共同点开始:并行化的动机是什么 -- 是的,性能。
如果我们都同意这一点,让我们回顾一下这个新的专业领域。
画个代码不难,就是这个烂到不行
能够理解和设计代码变得越来越重要,这些代码可以利用现代硬件基础架构来发挥其最大性能。
parallel-processing in general is intended for many other reasons, not just the performance -- your case, as proposed above, is at the end actually a "just"-[CONCURRENT]
-type of process-scheduling。不对-[PARALLEL]
?当然,如果它不是在拥有超过 21 CPU 核的机器上,超线程关闭并且所有操作系统进程暂时停止,直到所有 20 个示例在整个全球范围内来回处理最小化循环收敛了。
想象一下,您尝试 运行 仅 20 个机器学习输入(示例),而现实世界的数据集有数千个(在我的问题域中远远超过数十万个)示例要处理,所以在真正的[PARALLEL]
进程调度中永远不会陷入如此极端,使用这种方式。
Best start to understand the Amdahl's Law in its full context first ( an overhead-naive formulation does a bad service in this for freshmen experimentation -- better master in full-details also the Criticism section of the updated post on 首先是开销和资源限制,然后再投票支持“不惜任何代价 的并行化” -- even 如果有六个 "wannabe-gurus" 建议你这样做,那么今天有那么多以公关为动机的媒体大声疾呼你去平行 )。
。这与每个性能瓶颈审查和重新设计都相关。大多数神经网络花费大量时间( not 由于代码性能不佳,但由于巨大的数据集大小)重新运行ing 前馈 + 反向传播阶段,其中矢量化代码比使用普通 python 代码更难设计,但这是可以获得性能的地方,而不是损失。
Python 可以使用 numpy
中的智能矢量化工具,另外还可以通过系统地使用视图来设计您的代码以利用最小的开销,如果python-实现要显示其可能的速度,而不是在通过神经网络中的密集矩阵副本后重复进行内存分配时失去性能。
在很多情况下,无论代码采用何种工艺,仅编码都会产生非常糟糕的处理性能,而一些数学将显示计算过程和过程的智能重新设计-性能一下子跳了几个数量级( yes, 10x, 100x faster just by using human brain and critical thinking ).
是的,设计一个快速的代码很难,但没有人答应你免费吃晚餐,是吗?
最后但并非最不重要的一点:
永远不要让所有 [CONCURRENT]
-tasks 做完全相同的工作,越少重复它:
for c, w in zip( n.inconnections, range( len( n.inconnections ) ) ):
...
这种语法易于编码,但在每个 "wanted-to-get-accelerated" 任务中引入了重新计算的 zip()
处理。不。如果仍然考虑性能,确实是个坏主意。
我编写了一个运行速度非常慢的神经网络,所以我希望通过并行化某个循环来加快它的速度。
我不确定 GIL 的实现和工作方式,以及它是否与我相关。
代码如下所示:
class net():
def train(inputs)
...
for tset in batch:
self.backprop(tset, learn_rate)
def backprop(inputs):
...
for c, w in zip(n.inconnections, range(len(n.inconnections))):
c.current_error += n.current_error * n.inconnectionweights[w]
n.icweightupdates[w] += - learn_rate * n.current_error * c.activation
n.biasupdate += -learn_rate * n.current_error
train()
中的循环是我想要并行化的循环,因为 batch
包含一组可独立处理的训练样本 (20)。
Python 线程不会使它更快,因为 GIL。相反,您可以尝试流程:
import multiprocessing
class net():
def train(inputs)
...
with multiprocessing.Pool() as p:
biasupdates = p.map(lambda tset: self.backprop(tset, learn_rate), batch)
n.biasupdate += sum(biasupdates)
def backprop(inputs):
...
for c, w in zip(n.inconnections, range(len(n.inconnections))):
c.current_error += n.current_error * n.inconnectionweights[w]
n.icweightupdates[w] += - learn_rate * n.current_error * c.activation
return -learn_rate * n.current_error
当“AGILE”布道团的鼓声越来越响的时候,
永远不要在知道这样做有意义之前开始编码:
为什么?
您确实可以花费无限多的时间来编写一个甚至没有意义的东西,而 在适当的系统工程上花费合理的时间将帮助您确定哪些步骤是合理的,哪些是不合理的。
那么,让我们从一个共同点开始:并行化的动机是什么 -- 是的,性能。
如果我们都同意这一点,让我们回顾一下这个新的专业领域。
画个代码不难,就是这个烂到不行
能够理解和设计代码变得越来越重要,这些代码可以利用现代硬件基础架构来发挥其最大性能。
parallel-processing in general is intended for many other reasons, not just the performance -- your case, as proposed above, is at the end actually a "just"-[CONCURRENT]
-type of process-scheduling。不对-[PARALLEL]
?当然,如果它不是在拥有超过 21 CPU 核的机器上,超线程关闭并且所有操作系统进程暂时停止,直到所有 20 个示例在整个全球范围内来回处理最小化循环收敛了。
想象一下,您尝试 运行 仅 20 个机器学习输入(示例),而现实世界的数据集有数千个(在我的问题域中远远超过数十万个)示例要处理,所以在真正的[PARALLEL]
进程调度中永远不会陷入如此极端,使用这种方式。
Best start to understand the Amdahl's Law in its full context first ( an overhead-naive formulation does a bad service in this for freshmen experimentation -- better master in full-details also the Criticism section of the updated post on 首先是开销和资源限制,然后再投票支持“不惜任何代价 的并行化” -- even 如果有六个 "wannabe-gurus" 建议你这样做,那么今天有那么多以公关为动机的媒体大声疾呼你去平行 )。
Python 可以使用 numpy
中的智能矢量化工具,另外还可以通过系统地使用视图来设计您的代码以利用最小的开销,如果python-实现要显示其可能的速度,而不是在通过神经网络中的密集矩阵副本后重复进行内存分配时失去性能。
在很多情况下,无论代码采用何种工艺,仅编码都会产生非常糟糕的处理性能,而一些数学将显示计算过程和过程的智能重新设计-性能一下子跳了几个数量级( yes, 10x, 100x faster just by using human brain and critical thinking ).
是的,设计一个快速的代码很难,但没有人答应你免费吃晚餐,是吗?
最后但并非最不重要的一点:
永远不要让所有 [CONCURRENT]
-tasks 做完全相同的工作,越少重复它:
for c, w in zip( n.inconnections, range( len( n.inconnections ) ) ):
...
这种语法易于编码,但在每个 "wanted-to-get-accelerated" 任务中引入了重新计算的 zip()
处理。不。如果仍然考虑性能,确实是个坏主意。