Nie*_*ann 3 c optimization conditional-compilation c-preprocessor
我们正在研究一种模型检查工具,它可以执行几十亿次搜索程序.我们有不同的搜索例程,目前使用预处理器指令进行选择.这不仅非常不方便,因为我们每次做出不同的选择时都需要重新编译,但也使代码难以阅读.现在是开始新版本的时候了,我们正在评估是否可以避免条件编译.
这是一个非常人为的例子,显示了效果:
/* program_define */
#include <stdio.h>
#include <stdlib.h>
#define skip 10
int main(int argc, char** argv) {
int i, j;
long result = 0;
int limit = atoi(argv[1]);
for (i = 0; i < 10000000; ++i) {
for (j = 0; j < limit; ++j) {
if (i + j % skip == 0) {
continue;
}
result += i + j;
}
}
printf("%lu\n", result);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里,变量skip
是影响程序行为的值的示例.不幸的是,我们需要在每次需要新值时重新编译skip
.
让我们看看该程序的另一个版本:
/* program_variable */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int i, j;
long result = 0;
int limit = atoi(argv[1]);
int skip = atoi(argv[2]);
for (i = 0; i < 10000000; ++i) {
for (j = 0; j < limit; ++j) {
if (i + j % skip == 0) {
continue;
}
result += i + j;
}
}
printf("%lu\n", result);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里,值for skip
作为命令行参数传递.这增加了很大的灵活性 但是,这个程序要慢得多:
$ time ./program_define 1000 10
50004989999950500
real 0m25.973s
user 0m25.937s
sys 0m0.019s
Run Code Online (Sandbox Code Playgroud)
与
$ time ./program_variable 1000 10
50004989999950500
real 0m50.829s
user 0m50.738s
sys 0m0.042s
Run Code Online (Sandbox Code Playgroud)
我们正在寻找的是一种将值传递到程序中的有效方法(通过命令行参数或文件输入),后来永远不会改变.有没有办法优化代码(或告诉编译器),以便它更有效地运行?
任何帮助是极大的赞赏!
评论:
正如德克在评论中写道的那样,这不是关于具体的例子.我的意思是替换一个方法来替换一个方法来if
评估一个设置一次然后从未改变过的变量(比如一个命令行选项),这个函数被一个更有效的构造实际上被称为数十亿次.我们目前使用预处理器来定制所需的函数版本.如果有一种不需要重新编译的更好的方法会很好.
在libdivide
运行时不知道除数时,您可以查看哪些可以快速除法的工作:http://libdivide.com/.
如果您a % b
使用a - b * (a / b)
(但使用libdivide)计算,您可能会发现它更快.