我有一个函数var
。我想知道通过利用系统拥有的所有处理器、内核和RAM内存进行多处理/并行处理来快速运行该函数中循环的最佳方法
import numpy as np
from pysheds.grid import Grid
xs = 82.1206, 80.8707, 80.8789, 80.8871, 80.88715
ys = 25.2111, 16.01259, 16.01259, 16.01259, 15.9956
a = r'/home/test/image1.tif'
b = r'/home/test/image2.tif'
def var(interest):
variable_avg = []
for (x,y) in zip(xs,ys):
grid = Grid.from_raster(r'/home/data/data.tif', data_name='map')
grid.catchment(data='map', x=x, y=y, out_name='catch', recursionlimit=15000000, xytype='label')
grid.clip_to('catch')
grid.read_raster(interest, data_name='variable', window=grid.bbox, window_crs=grid.crs)
variablemask = grid.view('variable', nodata=np.nan)
variablemask = np.array(variablemask)
variablemean = np.nanmean(variablemask)
variable_avg.append(variablemean)
return(variable_avg)
如果我能为函数的给定多个参数同时运行函数var
和循环,那就太好了。
例如:同时调用var(a)
和var(b)
。因为它只需为多个坐标(xs,ys)并行循环就可以节省很多时间
pysheds
可以在here找到文档。
在grid = Grid.from_raster(r'/home/data/data.tif', data_name='map')
的代码中使用的data.tif
数据可以直接从here下载。相同的数据可以用不同的名称复制到目录中,并在a = r'/home/test/image1.tif'
处使用
和b = r'/home/test/image2.tif'
用于测试代码。
为了加速上述代码,我得到了一个建议here,如下所示:
def process_poi(interest, x, y):
grid = Grid.from_raster(interest, data_name='map')
grid.catchment(data='map', x=x, y=y, out_name='catch')
variable = grid.view('catch', nodata=np.nan)
variable = np.array(variable)
return variable.mean()
async def var_loop_async(interest, pool, loop):
tasks = []
for (x,y) in zip(xs,ys):
function_call = functools.partial(process_poi, interest, x, y)
tasks.append(loop.run_in_executor(pool, function_call))
return await asyncio.gather(*tasks)
async def main():
loop = asyncio.get_event_loop()
pool_start = time.time()
tasks = []
with ProcessPoolExecutor() as pool:
for _ in range(100):
tasks.append(var_loop_async(a, pool, loop))
results = await asyncio.gather(*tasks)
pool_end = time.time()
print(f'Process pool took {pool_end-pool_start}')
serial_start = time.time()
但是,我不明白如何调用函数var_loop_async(interest, pool, loop)
。事实上,我无法获得要调用哪些参数来代替pool
和loop
我对python编程非常陌生
如果可能,请将上述建议作为一个可复制的解决方案,以便可以直接在python中运行。或者,如果您有任何其他更好的建议,以加快原始代码,请一定要让我知道
首先,在您的原始代码中,我看到:
我不熟悉
pysheds
模块,也找不到任何关于它的文档,因此我不知道Grid.from_raster
是否是一个昂贵的操作。但这条语句似乎是在for
循环之上移动而不是在循环中重新计算的候选语句。也许仅此一项就可以显著提高性能。您提到的链接What all parameters to be called in a async function in python?表明,创建进程池的开销可能不足以弥补这些麻烦。此外,如果Grid.from_raster
很昂贵,并且通过将其从循环中移除而获利,那么多处理解决方案本质上通过使其对每个x,y对执行而“将其放回循环”,从而使多处理解决方案不太可能导致性能改进无论如何,要使用建议的技术运行代码,请参见下面的。不幸的是,您不能在处理器池中同时运行
process_poi
和var_loop_async
。但请在下面进一步寻找不同的解决方案不同的解决方案
您希望能够在进程池中为每个要处理的文件运行
var
,然后在子进程中处理每个x,y对。这意味着您需要处理文件的每个子进程都有自己的进程池来处理x,y对。这通常是不可能的,因为为进程池创建的进程是守护进程进程(它们在主进程终止时自动终止),并且不允许它们创建自己的子进程。为了克服这个问题,我们必须创建自己的mutliprocessor.Pool
专门化,并用自己的池初始化每个子进程但这会是一种性能改进吗除了等待
process_poi
子进程完成其工作外,var
子进程基本上什么也不做。因此,我不认为这比以前的代码有多大的改进。而且,正如我所提到的,目前还不清楚这两种多处理解决方案是否会比原始代码有所改进,尤其是修改为重新定位Grid.from_raster
调用的方案使用线程的第三种解决方案
使用
asyncio
:备选方案:
使用基于OP更新代码的线程更新解决方案
相关问题 更多 >
编程相关推荐