在运行时编译常量

时间:2010-07-07 15:47:00

标签: c performance compilation

我有一个用于某些科学模拟的程序,因此需要快速运行。

当我开始时,我有些懒惰,并决定允许稍后输入常量;并且只为它们使用了#define宏。

问题在于,当我尝试更改它时,它变慢了很多。例如,更改

#define WIDTH 8
//..... code

#define WIDTH width
int width;
//... main() {
width=atoi(argv[1]);
//...... code

导致过去需要花费2秒钟才能获得2.8。这仅仅是针对十几个常数中的一个,我甚至无法承受这一点。此外,可能还有一些与这些相关的数学计算。

所以我的问题是,我是否可以通过某种方式(bash脚本?)编译我想在运行时使用的常量。如果任何需要运行它的机器必须有一个编译器就可以了。它目前使用标准(非常简单)Makefile编译。
- 这也允许march = native,这应该有所帮助。

我想我的问题也是如果有更好的方法完全做到这一点......

3 个答案:

答案 0 :(得分:4)

至少如果我理解你的问题,我可能会做的事情就像:

#ifndef WIDTH
#define WIDTH 8
#endif

(同样适用于您希望能够修改的其他常量)。在你的makefile中,为makefile添加一些选项,以便在必要时将正确的定义传递给编译器,所以如果你想改变WIDTH,你会有类似的东西:

cflags=-DWIDTH=12

当你编译文件时,这将被用作WIDTH的定义,但是如果你没有在makefile中定义一个值,那么将使用源文件中的默认值。

答案 1 :(得分:2)

不同之处在于,宏只是一个整数文字,编译器通常能够在编译时计算一堆数学。一个简单的例子就是你有:

int x = WIDTH * 3;

编译器实际上会发出:

int x = 24;

没有在那里繁殖。如果将WIDTH更改为变量,则无法执行此操作,因为它可以是任何值。所以几乎肯定会有一些某些的速度差异(多少取决于环境,而且往往很少,无关紧要)。

我建议制作需要变量的变量然后进行分析以找到代码中的热点。几乎总是,这种算法会让你的速度降低。一旦你找到了你花费最多时间的代码块,那么你就可以找到使这部分更快的方法。

唯一真正的解决方案是拥有一个单独的头文件,其中包含可以生成脚本的常量,然后编译程序。或者,如果没有太多只是将它们直接传递给gcc。这当然牺牲了运行速度的前端速度。我想知道运行时间的0.8秒是否不合理,编译程序(肯定需要超过一秒)的成本如何?

脚本可以像这样简单:

#!/bin/sh

echo "#define WIDTH $1" > constants.h
echo "#define HEIGHT $2" >> constants.h
gcc prog.c -o prog && ./prog

其中prog.c包含constants.h或类似的东西(没有额外的标题)。

#!/bin/sh
gcc -DWIDTH=$1 -DHEIGHT=$2 prog.c -o prog && ./prog

答案 2 :(得分:1)

您可以将相关的定义存储到单独的头文件constants.h中:

#ifndef CONSTANTS_H
#define CONSTANTS_H

#define WIDTH 8
...other defines...

#endif

如果你只关注标题只包含一次,那么你甚至可以省略包含警戒并且只有一个只包含相关内容的小文件。如果程序被需要更改常量的其他人使用,我会这样做。如果你是唯一使用它的人,那么Jerry的方法就可以了。

修改

阅读你的评论,在编译之前,可以使用makefile中的一个小工具轻松生成这个单独的标题。