cython.parallel: 没有线程局部性的变量赋值

cython.parallel: variable assignment without thread-locality

使用 cython.parallel 我希望从 prange 线程中分配一个共享内存变量值,而无需隐式线程局部性。

或更不同的表述:


一些非常简单(无用)的伪代码来帮助说明我的问题:

cdef void some_func(*data, ...)
  found = 0
  for i in parallel.prange(no_of_chunks):
    for j in range(10000):
      if found == 1:
        break    # assuming break only quits its own for loop...
      if data[i*chunk_size+j] == something
        found = 1

上述代码段的想法是每个任务在处理其块时检查共享内存变量found。 (这可能很大,因此需要很长时间才能完全完成。)一旦一个线程找到它正在寻找的东西,它就会设置共享内存变量 found 导致所有其他线程立即存在。

不幸的是,据我了解文档,这不会发生:

If you assign to a variable in a prange block, it becomes lastprivate, meaning that the variable will contain the value from the last iteration.

据我了解,这意味着上述代码段的工作方式如下: - 一个线程找到它要找的东西,设置 found 并退出 - 所有其他线程继续使用其线程本地版本 found 并继续处理

我理解正确吗?

假设有人想在以下代码中共享 x

from cython.parallel import prange

cdef:
    Py_ssize_t i, n = 100
    int x = 0

with nogil:
    for i in prange(n, schedule='guided'):
        x = 1

当 cython 检测到分配 x = 1 并使用以下方法自动推断 xlastprivate 时出现问题:

#pragma omp for lastprivate(x)

为避免这种情况,可以使用指向 x 的解引用指针赋值:

from cython.parallel import prange
from cython import address

cdef:
    Py_ssize_t i, n = 100
    int x = 0
    int * px = address(x)

with nogil:
    for i in prange(n, schedule='guided'):
        px[0] = 1

当然,现在必须手动管理对共享资源的访问 x。以上代码在这方面不起作用。