编辑:我想到了一种使用预处理器来做到这一点的方法。这以使编译和链接稍微复杂一些为代价解决了重复代码的问题。它使用的功能是,如果在编译器中未启用 OpenMP,则会忽略 OpenMP 结构。
#include <stdlib.h>
void setQueen(int* x, int y, int z) {
/*code*/
}
#if defined _OPENMP
void solve_parallel(const int size)
#else
void solve_serial(const int size)
#endif
{
int i;
#pragma omp parallel for
for(i = 0; i < size; i++) {
int *queens = (int*)malloc(sizeof(int)*size);
setQueen(queens, 0, i);
free(queens);
}
}
编译
gcc -O3 -c foo.c -o solve_serial
gcc -O3 -fopenmp -c foo.c solve_parallel
然后,您可以使用类似于以下功能的主功能,并在solve_serial 和solve_parallel 目标文件中使用函数指针和链接。
另一种选择是像这样传递线程数:
void solve(const int nthreads)
{
int i;
const int size = 10;
#pragma omp parallel for num_threads(nthreads)
for(i = 0; i < size; i++) {
int *queens = (int*)malloc(sizeof(int)*size);
setQueen(queens, 0, i);
free(queens);
}
}
但是,即使对于 nthreads=1,编译器也必须插入 OpenMP 结构,与不使用 OpenMP 编译相比,这会降低性能,因此会产生有偏差的比较。
一个更公平的解决方案是定义两个有和没有 OpenMP 的函数,然后使用一个函数指针数组(见下文)。当您想要比较一个函数的多个变体以进行优化时,这会更有用。
#include <stdlib.h>
#include <omp.h>
void solve_parallel(const int size)
{
int i;
#pragma omp parallel for
for(i = 0; i < size; i++) {
int *queens = (int*)malloc(sizeof(int)*size);
setQueen(queens, 0, i);
free(queens);
}
}
void solve_serial(const int size)
{
int i;
for(i = 0; i < size; i++) {
int *queens = (int*)malloc(sizeof(int)*size);
setQueen(queens, 0, i);
free(queens);
}
}
int main(void) {
const int size = 100;
int i;
double dtime[2];
void (*solve[2])(int);
solve[0] = solve_serial;
solve[1] = solve_parallel;
solve[1](size); /* run OpenMP once to warm it up */
for(i=0; i<2; i++) {
dtime[i] = omp_get_wtime();
solve[i](size);
dtime[i] = omp_get_wtime() - dtime[i];
}
return 0;
}