【问题标题】:Achieve real parallelism python C-Extension实现真正的并行性 python C-Extension
【发布时间】:2016-03-14 11:17:39
【问题描述】:

我写了一个 python C 扩展。它工作正常。但是现在为了更高效的执行,我需要编写一个多线程/并行执行版本的相同扩展。

你能告诉我,如何编写一个同时在多个内核上运行的 Python C-Extension 代码。

我已经在这里打了一天多。请帮忙。

【问题讨论】:

    标签: python multithreading python-c-extension


    【解决方案1】:

    也许为时已晚,但希望对其他人有所帮助:)

    并行执行 C 扩展的最简单方法是使用 OPENMP API。来自wikipedia

    OpenMP(Open Multi-Processing)是一个应用程序编程接口 (API) 支持多平台共享内存多处理 在大多数平台上,使用 C、C++ 和 Fortran 编程,处理器 架构和操作系统。

    例如看这部分代码:

    int i;
    for (i=0;i<10;i++)
    {
        printf("%d ",i);
    }
    

    结果:

    0 1 2 3 4 5 6 7 8 9
    

    我们可以在for 语句块之前使用#pragma omp parallel for 编译器指令使其并行:

    int i;
    #pragma omp parallel for
    for (i=0;i<10;i++)
    {
        printf("%d ",i);
    }
    

    结果:

    0 1 5 8 9 2 6 4 3 7
    

    要在 gcc 中启用 openmp,您需要指定 -fopenmp 编译时标志。示例:

    gcc -fPIC -Wall -O3 costFunction.c -o costFunction.so -shared -fopenmp
    

    你可以从 HERE 学习 openmp。

    还有其他方法,例如pthread,但它是非常低级的。

    OpenMP 与 PThread: 来自HERE 的示例,用 C++ 编写。

    串行 C++ 代码:

    void sum_st(int *A, int *B, int *C){
       int end = 10000000;
       for(int i = 0; i < end; i++)
        A[i] = B[i] + C[i];
    }
    

    pthread 解决方案:

     struct params {
      int *A;
      int *B;
      int *C;
      int tid;
      int size;
      int nthreads;
    };
    
    void *compute_parallel(void *_p){
      params *p      = (params*) _p;
      int tid        = p->tid;
      int chunk_size = (p->size / p->nthreads);
      int start      = tid * chunk_size;
      int end        = start + chunk_size;
      for(int i = start; i < end; i++)     p->A[i] = p->B[i] + p->C[i];
      return 0;
    }
    
    void sum_mt(int *A, int *B, int *C){
      int nthreads = 4;
      int size = 10000000;
      pthread_t threads[nthreads]; //array to hold thread information
      params *thread_params = (params*) malloc(nthreads * sizeof(params));
    
      for(int i = 0; i < nthreads; i++){
        thread_params[i].A        = A;
        thread_params[i].B        = B;
        thread_params[i].C        = C;
        thread_params[i].tid      = i;
        thread_params[i].size     = size;
        thread_params[i].nthreads = nthreads;
        pthread_create(&threads[i], NULL, compute_parallel, (void*) &thread_params[i]);
      }
    
      for(int i = 0; i < nthreads; i++){
        pthread_join(threads[i], NULL);
      }
      free(thread_params);
    
    }
    

    OpenMP 解决方案:

    #pragma omp parallel for
    for(int i = 0; i < 10000000; i++)
      A[i] = B[i] + C[i];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-12
      • 1970-01-01
      • 2017-11-23
      • 2021-07-28
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多