并行化python:多处理与cython
我想并行化迭代,其中评估了许多cython实例实例,结果存储在全局numpy数组中:
for cythonInstance in myCythonInstances: success = cythonInstance.evaluate(someConstantGlobalVariables,) # very CPU intense if success == False: break globalNumpyArray[instanceSpecificLocation] = cythonInstance.resultVector[:] 实例评估的结果彼此独立.实例之间没有任何类型的交互,除了结果写入相同的全局数组,但是在固定的,预定的和独立的位置.如果一个评估失败,则必须停止迭代. 据我所知,有两种可能性: 我根本没有并行化的经验.哪种解决方案更可取,还是有更好的替代方案?谢谢! 解决方法
如果可以,请使用Cython:
> prange语法非常类似于range.它允许您采用编写Python循环的简单开发途径 – >将其转换为Cython – >将其转换为并行循环.希望每次所需的更改都很小.相比之下,多处理需要您将循环内部作为一个函数,然后设置ppols,因此它不那么熟悉. 您应该使用多处理时有一些特定情况: >你发现你需要获得很多GIL – 多处理不共享GIL所以不会减慢速度.如果你只需偶尔获得GIL,那么gil很小:Cython中的块通常不会让你减速太多,所以先试试吧. 查看代码的注意事项是,如果可以的话,应该避免使用Cython类.如果你可以将它重构为一个更好的cdef函数调用(Cython类有时候仍然需要GIL).类似于以下的东西会运作良好: cdef int f(double[:] arr,double loop_specific_parameter,int constant_parameter) nogil: # return your boolean to stop the iteration # modify arr return result # then elsewhere cdef int i cdef double[:,:] output = np.zeros(shape) for i in prange(len(parameters_to_try),nogil=True): result = f(output[i,:],parameters_to_try[i],constant_parameter) if result: break 我不建议使用Cython类的原因是1)你不能创建它们或在没有GIL的情况下索引它们的列表(出于引用计数的原因)和2)包括Cython类的Python对象似乎不是允许是本地线程.有关问题的示例,请参见Cython parallel prange – thread locality?. (原来我不知道成为当地人的限制) 涉及的with_gil开销不一定很大,所以如果这个设计最有意义的话就试试吧.查看您的CPU使用情况将告诉您它的并行化程度. 铌.即使您使用的是Cython而不是Python线程模块,this set of answers中的大部分优缺点仍然适用.不同之处在于您通常可以避免使用Cython中的GIL(因此使用线程的一些缺点不那么重要). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |