只有将-omp参数传递给程序时,是否有一种使用OpenMP并行化for循环的好方法? 这似乎是不可能的,因为#pragma omp parallel for是一个预处理器指令,因此甚至在编译时就进行了评估,当然只有在运
这似乎是不可能的,因为#pragma omp parallel for是一个预处理器指令,因此甚至在编译时就进行了评估,当然只有在运行时将参数传递给程序时才能确定.
目前我正在使用一个非常难看的解决方案来实现这一目标,这导致了大量的代码重复.
if(ompDefined) {
#pragma omp parallel for
for(...)
...
}
else {
for(...)
...
}
我认为您正在寻找的东西可以使用
CPU dispatcher technique来解决.
要对OpenMP代码与非OpenMP代码进行基准测试,您可以使用相同的源代码创建不同的目标文件
//foo.c
#ifdef _OPENMP
double foo_omp() {
#else
double foo() {
#endif
double sum = 0;
#pragma omp parallel for reduction(+:sum)
for(int i=0; i<1000000000; i++) sum += i%10;
return sum;
}
像这样编译
gcc -O3 -c foo.c gcc -O3 -fopenmp -c foo.c -o foo_omp.o
这将创建两个目标文件foo.o和foo_omp.o.然后你可以像这样调用其中一个函数
//bar.c
#include <stdio.h>
double foo();
double foo_omp();
double (*fp)();
int main(int argc, char *argv[]) {
if(argc>1) {
fp = foo_omp;
}
else {
fp = foo;
}
double sum = fp();
printf("sum %e\n", sum);
}
像这样编译和链接
gcc -O3 -fopenmp bar.c foo.o foo_omp.o
然后我像这样计算代码
time ./a.out -omp time ./a.out
第一种情况需要大约0.4秒,第二种情况需要大约1.2秒,我的系统有4核/ 8硬件线程.
这是一个只需要一个源文件的解决方案
#include <stdio.h>
typedef double foo_type();
foo_type foo, foo_omp, *fp;
#ifdef _OPENMP
#define FUNCNAME foo_omp
#else
#define FUNCNAME foo
#endif
double FUNCNAME () {
double sum = 0;
#pragma omp parallel for reduction(+:sum)
for(int i=0; i<1000000000; i++) sum += i%10;
return sum;
}
#ifdef _OPENMP
int main(int argc, char *argv[]) {
if(argc>1) {
fp = foo_omp;
}
else {
fp = foo;
}
double sum = fp();
printf("sum %e\n", sum);
}
#endif
像这样编译
gcc -O3 -c foo.c gcc -O3 -fopenmp foo.c foo.o
