2016-03-14 3 views
0

Я написал python C Extension. Его работа прекрасна. Но теперь для более эффективного выполнения мне нужно написать многопоточную/параллельную исполняемую версию того же расширения.Достигнуть реального параллелизма python C-Extension

Не могли бы вы рассказать мне, как написать код C-Extension Python, который работает на нескольких ядрах одновременно.

Я ударил здесь больше дня. Пожалуйста помоги.

ответ

2

может быть слишком поздно, но надеюсь, поможет другим людям :)

простого способа параллельно выполнения расширения C используют OPENMP API. от wikipedia:

OpenMP (Open Multi-Processing) представляет собой интерфейс прикладного программирования (API), который поддерживает мультиплатформенный общую память MultiProcessing программирования на 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 

для включения OpenMP в GCC вам нужно указать -fopenmp время компиляции флаг. Пример:

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

вы можете опереться OpenMP из HERE.

другие способы, такие как 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];