我有一个需要包含不同事物之和的数组,因此我想对它的每个元素进行归约。
这是代码:

cdef int *a=<int *>malloc(sizeof(int) * 3)
for i in range(3):
    a[i]=1*i
cdef int *b
for i in prange(1000,nogil=True,num_threads=10):
    b=res() #res returns an array initialized to 1s
    with gil: #if commented this line gives erroneous results
        for k in range(3):
            a[k]+=b[k]
for i in range(3):
    print a[i]


直到有了gil,代码才能正常运行,否则给出错误的结果。
如何在不使用gil的情况下处理数组每个元素的减少导致gil我认为gil会阻塞其他线程

最佳答案

减少操作通常在实践中起作用的方法是分别为每个线程求和,然后在最后将它们相加。您可以使用类似的方法手动执行此操作

cdef int *b
cdef int *a_local # version of a that is duplicated by each thread
cdef int i,j,k

# set up as before
cdef int *a=<int *>malloc(sizeof(int) * 3)
for i in range(3):
    a[i]=1*i

# multithreaded from here
with nogil, parallel(num_threads=10):
    # setup and initialise a_local on each thread
    a_local = <int*>malloc(sizeof(int)*3)
    for k in range(3):
        a_local[k] = 0

    for i in prange(1000):
        b=res() # Note - you never free b
                # this is likely a memory leak....

        for j in range(3):
            a_local[j]+=b[j]

    # finally at the end add them all together.
    # this needs to be done `with gil:` to avoid race conditions
    # but it isn't a problem
    # because it's only a small amount of work being done
    with gil:
        for k in range(3):
            a[k] += a_local[k]
    free(a_local)

关于python - cython并行中数组的减少,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36533455/

10-12 17:14