通常的模式是每个线程都有自己的容器,这是速度/复杂度与内存开销之间的权衡:
- 无需锁定即可访问此容器,因为只有一个线程可以访问它。
- 与“每个任务都有自己的容器(即每个
i
值)”相比,开销要少得多。
在并行部分之后,必须在后处理步骤中将数据收集在最终容器中(这也可以并行发生),或者后续算法应该能够处理容器的收集。
以下是使用c ++-vector的示例(已经具有内存管理功能并内置了增加的大小):
%%cython -+ -c=/openmp --link-args=/openmp
from cython.parallel import prange,threadid
from libcpp.vector cimport vector
cimport openmp
def calc_in_parallel(N):
cdef int i,k,tid
cdef int n = N
cdef vector[vector[int]] vecs
# every thread gets its own container
vecs.resize(openmp.omp_get_max_threads())
for i in prange(n,nogil=True):
tid = threadid()
for k in range(i):
# use container of the thread
vecs[tid].push_back(k) # dummy for calculation
return vecs
在许多情况下,将omp_get_max_threads()
用于线程数会高估实际线程数。在prange
中显式设置线程数(即
)可能更可靠。
...
NUM_THREADS = 2
vecs.resize(NUM_THREADS)
for i in prange(n,nogil=True,num_threads = NUM_THREADS):
...
使用纯C可以应用类似的方法,但是在这种情况下将需要更多的样板代码(内存管理)。
本文链接:https://www.f2er.com/3123954.html