在不使用条件编译的情况下加速C程序

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评估一个设置一次然后从未改变过的变量(比如一个命令行选项),这个函数被一个更有效的构造实际上被称为数十亿次.我们目前使用预处理器来定制所需的函数版本.如果有一种不需要重新编译的更好的方法会很好.

Sop*_*ert 5

libdivide运行时不知道除数时,您可以查看哪些可以快速除法的工作:http://libdivide.com/.

如果您a % b使用a - b * (a / b)(但使用libdivide)计算,您可能会发现它更快.