python 2.7我试图在所有内核上分发二维数组的计算。
为之
import itertools as it
import multiprocessing as mp
temp_env = 20
c = 0.25
a = 0.02
arr = np.ones((100,100))
x = arr.shape[0]
y = arr.shape[1]
new_arr = np.zeros((x,y))
def calc_inside(idx):
new_arr[idx[0],idx[1]] = ( arr[idx[0], idx[1] ]
+ c * ( arr[idx[0]+1,idx[1] ]
+ arr[idx[0]-1,idx[1] ]
+ arr[idx[0], idx[1]+1]
+ arr[idx[0], idx[1]-1]
- arr[idx[0], idx[1] ]*4
)
- 2 * a
* ( arr[idx[0], idx[1] ]
- temp_env
)
)
inputs = it.product( range( 1, x-1 ),
range( 1, y-1 )
)
p = mp.Pool()
p.map( calc_inside, inputs )
#for i in inputs:
# calc_inside(i)
#plot arrays as surface plot to check values
假设阵列arr
具有一些附加的初始化,除了示例性的1
-S以外的一些不同值,因此计算(温度的迭代计算)实际上是有道理的。
当我使用注释的 for
-loop时,而不是 Pool.map()
方法时,一切都可以正常工作,并且数组实际上包含值。使用Pool()
函数时,变量new_array
仅保持其初始化状态(这意味着它仅包含零,因为它最初是用它初始化的)。
Q1:这是否意味着Pool()
阻止写入全局变量?
Q2:还有其他方法可以通过并行处理解决此问题?
a1:
您的代码实际上不使用使用 global <variable>
语法声明的任何变量。但是,不要尝试尝试使用它们,而是越少于分布式处理。
A2:
是的,可以并行处理,但是最好在花费(浪费)努力之前彻底了解这样做的成本,这从来没有证明这样做的成本是合理的。
为什么要开始费用?
您会向您的银行业务员支付$ 2.00的金额,仅收取$ 1.00的钞票?
猜猜没人会做的。
尝试并行进行。
语法是" free "和&quot" 有希望的&quort;简单且外观良好的语法构建程序实际执行的语法成本不是。期望令人震惊的惊喜,而不是免费获得任何晚餐。
实际费用是多少?基准。基准。基准!
有用的工作
您的代码实际上只能进行几个内存访问和一些浮点操作。块和退出。这些flop-s少于几个 [ns]
max在最近的CPU频率上 [us]
的几个单位〜2.6 ~ 3.4 [GHz]
。做基准:
from zmq import Stopwatch; aClk = Stopwatch()
temp_env = 20
c = 0.25
a = 0.02
aClk.start()
_ = ( 1.0
+ c * ( 1.0
+ 1.0
+ 1.0
+ 1.0
- 1.0 * 4
)
- 2 * a
* ( 1.0
- temp_env
)
)
T = aClk.stop()
so,纯 [SERIAL]
-process在四核CPU上执行,不会比T+T+T+T
差(一个接一个地执行)。
+-+-+-+--------------------------------- on CpuCore[0]
: : : :
<start>| : : : :
|T| : : :
. |T| : :
. |T| :
. |T|
. |<stop>
|<----->|
= 4.T in a pure [SERIAL]-process schedule on CpuCore[0]
如果相同数量的有用的工作将在现在的某些形式的 [CONCURRENT]
-process execution(使用multiprocessing.Pool
的方法)中实施,将会发生什么情况。,有可能出于相同目的使用更多的CPU核?
实际的计算相,不会持续少于 T
再次,对吗?为什么会呢?是的,永远不会。
A.......................B...............C.D Cpu[0]
<start>| : : : :
|<setup a subprocess[A]>| : :
. | :
. |<setup a subprocess[B]>|
. | +............+........................... Cpu[!0]
. | : : |
. |T| : |
. |<ret val(s) | | +............+... Cpu[!0]
. | [A]->main| | : :
. |T| :
. |<ret val(s) |
. | [B]->main|
.
.
. .. |<stop>
|<--------------------------------------------------------- .. ->|
i.e. >> 4.T ( while simplified, yet the message is clear )
开销即。您将始终每笔电话支付的费用(确实很多次)
子进程设置 终止成本(基准标准学习这些费用的量表)。内存访问成本(延迟,零缓存重复使用在您退出时碰巧有帮助)。
结语
希望视觉消息已经足够清楚,可以始终在确定将重新工程代码重新设计为分布式流程,具有多核或具有多核或具有多核或具有多核或具有多核的任何可实现的好处之前,请开始计算应计成本甚至多核[CONCURRENT]
面料。