c - 仅在将参数传递给程序时使用 openMP
问题描述
有没有一种使用 OpenMP 并行化 for 循环的好方法,只有在将-omp
参数传递给程序的情况下?
这似乎是不可能的,因为#pragma omp parallel for
它是一个预处理器指令,因此甚至在编译时间之前就进行了评估,当然只有在运行时将参数传递给程序才能确定。
目前我正在使用一个非常丑陋的解决方案来实现这一点,这会导致大量的代码重复。
if(ompDefined) {
#pragma omp parallel for
for(...)
...
}
else {
for(...)
...
}
解决方案
我认为您正在寻找可以使用CPU 调度程序技术来解决。
为了对 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
推荐阅读
- json - 将 JSON 对象输出到单独的行
- c# - 当我在查询字符串参数中发送逗号时,twitter api“更新/状态”返回 401
- c++ - 使用 gcc 而不是 g++ 输出二进制文件的大小更小
- javascript - 在子页面点击图片加载视频
- machine-learning - 图像像素可以存储在一维数组中吗?
- google-apps-script - Google Meet startTimeCode 使用,是否可以从电子表格单元格中查找?
- maven - 以管理员身份运行 shell 时无法识别 Maven
- r - Rstudio:使用 for 循环求解方程
- ios - 如何使用 SwiftUI 在导航栏上添加按钮
- css - 如何将文本粘贴到页面底部