我有一个可以并行化的问题:我需要对24个cdef对象执行相同的操作。我知道我可以为此使用多进程,但是复制数据/启动一个新进程只需要串行执行计算,那么就什么也得不到。因此,openMP可能是更好的选择。
我要执行的操作在多处理中看起来像这样:
multiprocess.map(f, list_of_cython_objects)
像下面这样的东西行吗?为什么/为什么不呢?我知道我必须创建一个指向cython对象的指针数组,我不能使用列表。
from cython.parallel import prange, threadid
with nogil, parallel():
for i in prange(len(list_of_cython_objects), schedule='guided'):
f(list_of_cython_objects[i])
答案 0 :(得分:2)
假设大多数f
可以在没有GIL的情况下完成(即,它使用cdef
的{{1}}属性),则可以使其工作得很好。唯一需要GIL的位是为列表编制索引,您可以轻松地将其放在cdef class
块中。
一个说明性的例子是:
with gil
只要from cython.parallel import prange, parallel
cdef class C:
cdef double x
def __init__(self,x):
self.x = x
cdef void f(C c) nogil:
c.x *= 2
def test_function():
list_of_cython_objects = [ C(x) for x in range(20) ]
cdef int l = len(list_of_cython_objects)
cdef int i
cdef C c
with nogil, parallel():
for i in prange(l, schedule='guided'):
with gil:
c = list_of_cython_objects[i]
f(c)
块很小(就计算时间的比例而言),您就应该获得所需的大部分并行化加速。