for cythonInstance in myCythonInstances: success = cythonInstance.evaluate(someConstantGlobalVariables,) # very cpu intense if success == False: break globalNumpyArray[instanceSpecificLocation] = cythonInstance.resultVector[:]
实例评估的结果彼此独立.实例之间没有任何类型的交互,除了结果写入相同的全局数组,但是在固定的,预定的和独立的位置.如果一个评估失败,则必须停止迭代.
据我所知,有两种可能性:
1)使用多处理包
2)制作一个cython函数并使用prange / openmp.
我根本没有并行化的经验.哪种解决方案更可取,还是有更好的替代方案?谢谢!
解决方法 如果可以,请使用Cython:> prange语法非常类似于range.它允许您采用编写Python循环的简单开发途径 – >将其转换为Cython – >将其转换为并行循环.希望每次所需的更改都很小.相比之下,多处理需要您将循环内部作为一个函数,然后设置ppols,因此它不那么熟悉.
> OpenMP / Cython线程的开销很低.相反,多处理模块的开销相对较高(“进程”通常比“线程”慢).
>多处理在windows中受到很大限制(一切都必须是可选择的).这经常是一件非常麻烦的事.
您应该使用多处理时有一些特定情况:
>你发现你需要获得很多GIL – 多处理不共享GIL所以不会减慢速度.如果你只需偶尔获得GIL,那么gil很小:Cython中的块通常不会让你减速太多,所以先试试吧.
>你需要同时做一堆完全不同的 *** 作(即不适合prange循环的东西,因为每个线程真正运行单独的代码).如果是这种情况,Cython prange语法并不适合.
查看代码的注意事项是,如果可以的话,应该避免使用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 elsewherecdef int icdef 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(因此使用线程的一些缺点不那么重要).
总结以上是内存溢出为你收集整理的并行化python:多处理与cython全部内容,希望文章能够帮你解决并行化python:多处理与cython所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)