2016-03-14 31 views
0

我已經寫了一個python C擴展。它的工作正常。但現在爲了更高效的執行,我需要編寫同一擴展的多線程/並行執行版本。實現真正的並行python C-Extension

請問您可以告訴我,如何編寫同時在多個核心上運行的Python C-Extension代碼。

我已經在這裏打了一天以上。請幫忙。

回答

2

也許爲時已晚,但希望可以幫助別人:)

並行使用OPENMP API C擴展的執行最簡單的方法。從wikipedia

OpenMP的(開放多處理)是一種應用程序編程接口 (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 

,我們可以把它平行使用#pragma omp parallel for編譯器指令之前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]; 
} 

並行線程溶液:

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];