Cython 中的共享地址 space
Shared address space in Cython
我有以下 Cython
代码:
from cython import parallel
from libc.stdio cimport printf
cdef extern from "unistd.h" nogil:
int usleep(int);
def test_func():
cdef int var = -1
with nogil, parallel.parallel(num_threads=4):
var = parallel.threadid()
usleep(100000)
printf("Var: %d\n", var)
在 python3
控制台中编译和启动后,我得到:
>>> import test
>>> test.test_func()
Var: 3
Var: 0
Var: 2
Var: 1
也就是说,每个线程都有自己的地址space。
但是,我想要 C++
OpenMP
行为,复制这个:
#include "omp.h"
#include <stdio.h>
#include <unistd.h>
int main() {
int v=-1;
omp_set_num_threads(4);
#pragma omp parallel
{
v=omp_get_thread_num();
usleep(100000);
printf("Var: %d\n", v);
}
return(0);
}
输出如下:
Var: 3
Var: 3
Var: 3
Var: 3
因此,问题:是否有可能在 Cython
个并行块中获得共享地址 space?
这样做有点笨拙,但是使用指向 var
的指针似乎可以欺骗它
def test_func2():
cdef int var = -1
cdef int* var_ptr = &var
with nogil, parallel.parallel(num_threads=4):
var_ptr[0] = parallel.threadid()
usleep(100000)
printf("Var: %d\n", var)
如果您查看生成的 C 代码,那么 test_func
(您的版本)会给出行
#pragma omp parallel private(__pyx_v_var) num_threads(4)
而 test_func2
给出
#pragma omp parallel num_threads(4)
我认为这是可行的,因为您没有直接分配给它,所以它不会被 Cython 的关于私有化内容的正常规则所接受。这里有一个风险——如果 Cython 的未来版本变得更聪明并将 var_ptr
设为私有,那么它不会在并行部分开始时被初始化(所以要小心并检查它在做什么!)。
我有以下 Cython
代码:
from cython import parallel
from libc.stdio cimport printf
cdef extern from "unistd.h" nogil:
int usleep(int);
def test_func():
cdef int var = -1
with nogil, parallel.parallel(num_threads=4):
var = parallel.threadid()
usleep(100000)
printf("Var: %d\n", var)
在 python3
控制台中编译和启动后,我得到:
>>> import test
>>> test.test_func()
Var: 3
Var: 0
Var: 2
Var: 1
也就是说,每个线程都有自己的地址space。
但是,我想要 C++
OpenMP
行为,复制这个:
#include "omp.h"
#include <stdio.h>
#include <unistd.h>
int main() {
int v=-1;
omp_set_num_threads(4);
#pragma omp parallel
{
v=omp_get_thread_num();
usleep(100000);
printf("Var: %d\n", v);
}
return(0);
}
输出如下:
Var: 3
Var: 3
Var: 3
Var: 3
因此,问题:是否有可能在 Cython
个并行块中获得共享地址 space?
这样做有点笨拙,但是使用指向 var
的指针似乎可以欺骗它
def test_func2():
cdef int var = -1
cdef int* var_ptr = &var
with nogil, parallel.parallel(num_threads=4):
var_ptr[0] = parallel.threadid()
usleep(100000)
printf("Var: %d\n", var)
如果您查看生成的 C 代码,那么 test_func
(您的版本)会给出行
#pragma omp parallel private(__pyx_v_var) num_threads(4)
而 test_func2
给出
#pragma omp parallel num_threads(4)
我认为这是可行的,因为您没有直接分配给它,所以它不会被 Cython 的关于私有化内容的正常规则所接受。这里有一个风险——如果 Cython 的未来版本变得更聪明并将 var_ptr
设为私有,那么它不会在并行部分开始时被初始化(所以要小心并检查它在做什么!)。