我在项目中工作,我有以下代码:
file1.c中
extern const int z;
int x;
do_some_stuff_to_calculate_x();
y = x / z;
do_some_stuff_with_y();
file2.c中
const int z = Z_INIT_VALUE; // some value defined in some .h file.
兴趣点是file1.c
中的分歧。由于z
是extern
,因此在编译时不知道[它将在链接时间中定义]。
因此,编译器无法优化除法。
我知道如果在编译时知道z
的值,编译器会将除法转换为乘法和其他一些操作。
请注意,file1.c将作为库提供,因此不能选择使用file1.c
重新编译file2.c
。
有没有人知道让链接器优化这些东西? 或者其他任何避免这种昂贵分裂的技巧?
Thx:)
更新:
好吧,在我看到一些答案后,我注意到需要更多细节才能使这个问题更具信息性。
包括除法的功能通常如下所示。
extern const int common_divisor;
extern const int common_addition;
void handleTheDamnInterrupt(void)
{
int x = *(REG_FOO_1);
int y = x / common_divisor;
y += common_addition;
if( x > some_value )
{
y += blah_blah;
}
else
{
y += foo_bar;
}
*(REG_BAR_1) = y;
}
此功能是所有程序中的典型功能形式。无法确切地知道划分对节目有多大影响,因为我有很多这些功能具有不同的周期性
但是当我尝试从extern
移除const
并给它任意值时,它会更好。
答案 0 :(得分:3)
您可以自己进行相同的优化,在初始化时执行一些设置计算。 Terje Mathisen发明的将整数除法转换为乘法的算法如下所述:http://www.asdf.org/~fatphil/x86/pentopt/27.html
答案 1 :(得分:2)
Microsoft链接器,其中一个,将优化它。它被称为“链接时代码生成”。 Here's an article about it(已过时,但仍然有用)。它已打开/LTCG
flag。
答案 2 :(得分:2)
如果我看过它,这是微观优化。您应该对一些结果进行分析,并可能编辑您的问题,这些结果表明为什么优化这一整数运算非常重要。
如果z
确实是常量并且是从预处理程序符号初始化的,只需将该符号放在库的标题中,然后停止将其作为运行时变量引入。
答案 3 :(得分:0)
您对do_some_stuff
的调用将远远超过整数除法。