python - cython.并行 : variable assignment without thread-locality

标签 python multithreading parallel-processing openmp cython

使用cython.parallel我希望在没有隐式线程局部性的情况下从 prange 线程分配共享内存变量值。

或者用更不同的方式表述:

  • 如何使用 cython.parallel 将变量定义为 openmp shared 而不是 private
  • 不同的线程或prange block 如何通信?
<小时/>

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

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

上述代码段的想法是,每个任务在处理其 block 时检查共享内存变量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的访问。上面的代码在这方面不起作用。

关于python - cython.并行 : variable assignment without thread-locality,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28754630/

相关文章:

ios - 在从服务器加载图像之前加载 "Loading"图像?

c++ - pthread_mutex_lock 阻塞但 __lock = 0

c++ - 使用 Intel TBB 用随机数填充数组

python - 在 Numpy 中执行 `A[tuple(B.T)]` 的更快方法

python - 属性错误 : 'Price' object has no attribute 'update'

java - JAVA中无等待队列的实现

c - C中的并行编程

scala - 如何控制scala并行集合的并发度

Python - 使用 xlsxwriter 创建依赖下拉列表

python - configparser.NoSectionError : No section: 'myvars'