Cython中的共享地址空间

时间:2015-11-10 11:17:58

标签: openmp 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

这意味着,每个线程都有自己的地址空间。

但是,我希望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并行块中获得共享地址空间?

1 个答案:

答案 0 :(得分:1)

这有点像一种hacky方式,但使用指向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变为私有,那么它将不会在并行部分的开始处初始化(所以要小心并检查它正在做什么!)。