在cython中有线程局部数组,以便我可以调整它们的大小?

我有一个间隔树算法,我想对许多使用线程的查询并行运行。问题在于每个线程都需要一个自己的数组,因为我事先无法知道会有多少次命中。

还有其他类似的问题,建议的解决方案始终是使用大小为(K,t)的数组,其中K是输出长度,t是线程数。这对我不起作用,因为每个线程的K可能不同,并且每个线程可能需要调整数组的大小以适合其获得的所有结果。

伪代码:

for i in prange(len(starts)):

    qs,qe,qx = starts[i],ends[i],index[i]

    results = t.search(qs,qe)

    if len(results) + nfound < len(output):
        # add result to output
    else:
        # resize array
        # then add results
xiongming321 回答:在cython中有线程局部数组,以便我可以调整它们的大小?

通常的模式是每个线程都有自己的容器,这是速度/复杂度与内存开销之间的权衡:

  1. 无需锁定即可访问此容器,因为只有一个线程可以访问它。
  2. 与“每个任务都有自己的容器(即每个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

大家都在问