cython.parallel: 没有线程局部性的变量赋值
cython.parallel: variable assignment without thread-locality
使用 cython.parallel
我希望从 prange
线程中分配一个共享内存变量值,而无需隐式线程局部性。
或更不同的表述:
- 如何使用
cython.parallel
将变量定义为 openmp shared
而不是 private
?
- 不同的线程或
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
并使用以下方法自动推断 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
。以上代码在这方面不起作用。
使用 cython.parallel
我希望从 prange
线程中分配一个共享内存变量值,而无需隐式线程局部性。
或更不同的表述:
- 如何使用
cython.parallel
将变量定义为 openmpshared
而不是private
? - 不同的线程或
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
并使用以下方法自动推断 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
。以上代码在这方面不起作用。