我使用PRANGE過像這樣的列表迭代:Cython並行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在線程中被覆蓋?我究竟做錯了什麼 ?謝謝!
你說得對。它似乎並沒有讓'tEl'線程局部(看看生成的C文件,並搜索'lastprivate'來檢查)。如果您將其更改爲基本類型(如'double'),它可以工作,但似乎不適用於Cython對象類型。我不知道一個明顯的解決方案,但它可能是值得在github上提供一個錯誤 – DavidW