只有将-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