gpt4 book ai didi

multithreading - Cython 并行 prange - 线程局部性?

转载 作者:行者123 更新时间:2023-12-03 12:54:41 26 4
gpt4 key购买 nike

我在这样的列表上使用 prange 进行迭代:

from cython.parallel import  prange, threadid

cdef int tid
cdef CythonElement tEl
cdef int a, b, c

# elList: python list of CythonElement instances is passed via function call
for n in prange(nElements, schedule='dynamic', nogil=True):
with gil:
tEl = elList[n]
tid = threadid()
a = tEl.a
b = tEl.b
c = tEl.c

print("thread {:} elnumber {:}".format(tid, tEl.elNumber))

#nothing is done here

with gil:
print("thread {:} elnumber {:}".format(tid, tEl.elNumber))

# some other computations based on a, b and c here ...

我期待这样的输出:
thread 0 elnumber 1
thread 1 elnumber 2
thread 2 elnumber 3
thread 3 elnumber 4
thread 0 elnumber 1
thread 1 elnumber 2
thread 2 elnumber 3
thread 3 elnumber 4

但我得到:
thread 1 elnumber 1
thread 0 elnumber 3
thread 3 elnumber 2
thread 2 elnumber 4
thread 3 elnumber 4
thread 1 elnumber 2
thread 0 elnumber 4
thread 2 elnumber 4

那么,不知何故,线程局部变量 tEl 被跨线程覆盖了?我究竟做错了什么 ?谢谢!

最佳答案

看起来 Cython 故意选择从线程局部变量列表中排除任何 Python 变量(包括 Cython cdef class es)。 Code

我怀疑这是故意避免引用计数问题 - 他们需要在循环结束时删除所有线程局部变量的引用计数(这不是一个无法解决的问题,但可能是一个很大的变化) .因此,我认为它不太可能被修复,但文档更新可能会有所帮助。

解决方案是将您的循环体重构为一个函数,其中每个变量最终都有效地“本地”到函数中,因此它不是问题:

cdef f(CythonElement tEl):
cdef int tid
with nogil:
tid = threadid()
with gil:
print("thread {:} elnumber {:}".format(tid, tEl.elNumber))

with gil:
print("thread {:} elnumber {:}".format(tid, tEl.elNumber))

# I've trimmed the function a bit for the sake of being testable

# then for the loop:
for n in prange(nElements, schedule='dynamic', nogil=True):
with gil:
f()

关于multithreading - Cython 并行 prange - 线程局部性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42144545/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com