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

时间:2015-02-26 23:13:22

标签: python multithreading parallel-processing openmp cython

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

或者更不同地制定:

  • 如何使用shared将变量定义为openmp private而不是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,导致所有其他线程立即存在。 / p>

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

  

如果您分配到prange块中的变量,它将变为lastprivate,   意味着变量将包含最后一个值   迭代。

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

我是否正确理解了这一点?

1 个答案:

答案 0 :(得分:3)

假设有人希望在以下代码中共享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的访问。上面的代码在这方面不起作用。