在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
- 循环而不是Pool.map()
方法时,一切正常,数组实际上包含值。使用Pool()
函数时,变量new_array
只保持其初始化状态(意味着它只包含零,因为它最初初始化时)。
Q1:这是否意味着Pool()
阻止写入全局变量?
Q2:还有其他方法可以解决并行化问题吗?
答案 0 :(得分:0)
A1:
您的代码实际上不使用使用 global <variable>
语法声明的任何变量。尽管如此,不要尝试使用它们,进入分布式处理的次数越少。
A2:
是的,进行并行化是可能的,但是在花费(嗯,浪费)努力之前,最好能够全面了解这样做的成本,从而无法证明这样做的成本。
您是否需要向银行职员支付2.00美元才能获得一张价值1.00美元的钞票?
猜猜没人会做。
尝试并行也是如此。
语法是“免费”和“承诺”, 实际执行简单且外观漂亮的语法构造函数的语法成本不是。期待相当令人震惊的惊喜,而不是免费享用任何晚餐。
有用的工作
您的代码实际上只执行了一些内存访问,并在块内部进行了一些浮点操作并退出。这些FLOP-s在最近的CPU频率上只需要几个 [ns]
最多 [us]
〜2.6 ~ 3.4 [GHz]
。 benchmark it:
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()
因此,四核CPU上的纯 [SERIAL]
-process执行不会比约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执行的某种形式中强制执行相同数量的有用工作,将会发生什么情况(使用{ {1}}的方法),可能为了相同的目的使用更多的CPU内核?
实际的计算阶段,不会再次持续 multiprocessing.Pool
,对吗?为什么会这样?是的,永远不会。
T
开销 即。每次通话总是支付的费用(确实很多次)
子流程设置+终止费用( benchmark it 以了解这些费用的比例)
内存访问成本(延迟,在您退出时,零缓存重用会发生帮助)。
希望可视化消息足够清晰,以便始终开始计算应计成本,然后再决定将代码重新设计为分布式流程流,具有多核或多核的任何可实现的好处甚至可以使用多核 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 )
面料。