【发布时间】:2016-03-14 11:17:39
【问题描述】:
我写了一个 python C 扩展。它工作正常。但是现在为了更高效的执行,我需要编写一个多线程/并行执行版本的相同扩展。
你能告诉我,如何编写一个同时在多个内核上运行的 Python C-Extension 代码。
我已经在这里打了一天多。请帮忙。
【问题讨论】:
标签: python multithreading python-c-extension
我写了一个 python C 扩展。它工作正常。但是现在为了更高效的执行,我需要编写一个多线程/并行执行版本的相同扩展。
你能告诉我,如何编写一个同时在多个内核上运行的 Python C-Extension 代码。
我已经在这里打了一天多。请帮忙。
【问题讨论】:
标签: python multithreading python-c-extension
也许为时已晚,但希望对其他人有所帮助:)
并行执行 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];
【讨论】: