【发布时间】:2020-02-21 23:30:39
【问题描述】:
我正在尝试在我所做的每个迷你项目中学习一些新的东西。我制作了一个生命游戏(https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life)程序。
这涉及一个 numpy 数组,其中数组中的每个点(“单元格”)都有一个整数值。要演化游戏状态,您必须为每个单元计算其所有相邻值(8 个相邻值)的总和。
我的代码中的相关类如下,其中evolve() 采用xxx_method 方法之一。它适用于conv_method 和loop_method,但我想在loop_method 上使用多处理(我已经确定它应该可以工作,不像多线程?)来查看任何性能提升。我觉得它应该起作用,因为每个计算都是独立的。我尝试了一种天真的方法,但对多处理模块的理解还不够好。我是否也可以在evolve() 方法中使用它,因为我再次觉得双for 循环中的每个计算都是独立的。
任何帮助表示赞赏,包括通用代码 cmets。
编辑 - 我收到了一个 RuntimeError,因为我对多处理的理解不够好,所以我有一半的预期。需要对代码执行什么操作才能使其正常工作?
class GoL:
""" Game Engine """
def __init__(self, size):
self.size = size
self.grid = Grid(size) # Grid is another class ive defined
def evolve(self, neigbour_sum_func):
new_grid = np.zeros_like(self.grid.cells) # start with everything dead, only need to test for keeping/turning alive
neighbour_sum_array = neigbour_sum_func()
for i in range(self.size):
for j in range(self.size):
cell_sum = neighbour_sum_array[i,j]
if self.grid.cells[i,j]: # already alive
if cell_sum == 2 or cell_sum == 3:
new_grid[i,j] = 1
else: # test for dead coming alive
if cell_sum == 3:
new_grid[i,j] = 1
self.grid.cells = new_grid
def conv_method(self):
""" Uses 2D convolution across the entire grid to work out the neighbour sum at each cell """
kernel = np.array([
[1,1,1],
[1,0,1],
[1,1,1]],
dtype=int)
neighbour_sum_grid = correlate2d(self.grid.cells, kernel, mode='same')
return neighbour_sum_grid
def loop_method(self, partition=None):
""" Also works out neighbour sum for each cell, using a more naive loop method """
if partition is None:
cells = self.grid.cells # no multithreading, just work on entire grid
else:
cells = partition # just work on a set section of the grid
neighbour_sum_grid = np.zeros_like(cells) # copy
for i, row in enumerate(cells):
for j, cell_val in enumerate(row):
neighbours = cells[i-1:i+2, j-1:j+2]
neighbour_sum = np.sum(neighbours) - cell_val
neighbour_sum_grid[i,j] = neighbour_sum
return neighbour_sum_grid
def multi_loop_method(self):
cores = cpu_count()
procs = []
slices = []
if cores == 2: # for my VM, need to impliment generalised method for more cores
half_grid_point = int(SQUARES / 2)
slices.append(self.grid.cells[0:half_grid_point])
slices.append(self.grid.cells[half_grid_point:])
else:
Exception
for sl in slices:
proc = Process(target=self.loop_method, args=(sl,))
proc.start()
procs.append(proc)
for proc in procs:
proc.join()
【问题讨论】:
标签: python optimization multiprocessing conways-game-of-life