使用cython.parallel
我希望在没有隐式线程局部性的情况下从 prange
线程分配共享内存变量值。
或者用更不同的方式表述:
- 如何使用
cython.parallel
将变量定义为 openmpshared
而不是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
并自动推断 x
为 lastprivate
时,会出现问题:
#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/