2011-12-12 38 views
5

有什么办法可以告诉编译器,你知道某个特定变量的值必须在代码中某个特定位置的特定范围内,才能帮助编译器进行优化?我正在编写一个库,它可以在编译时知道一些变量的范围,如果能够以某种方式将此信息传递给编译器以便编译器可以使用它来进行优化,那么它会很好用。我想增加对任何编译器的支持,即使这些编译器无法为所有编译器工作(这听起来像某些编译器可以作为扩展的东西,但我没有发现任何)。我知道我可以写这样的东西:如何将范围信息传递给C++编译器?

if(x < COMPILE_TIME_MIN or x > COMPILE_TIME_MAX) 
    return; 
// compiler will assume for code below that x is in range COMPILE_TIME_MIN..COMPILE_TIME_MAX 

但这是一个运行时检查。也许有一些技巧让编译器做出范围的假设,而没有这样的检查?

+2

你有什么想法可以帮助哪种类型的优化? –

+0

如果使用模板,实际上可以编译时检查编译时是否知道所有的信息。 –

+0

您正在使用“编译器”这个短语,但您永远不会告诉我们哪一个。推测你的意思是某种版本的g ++或Visual C++,但这并不清楚。标准并没有解决一般的优化问题,所以你可能在这里做的任何事情都是特定于实现的。 –

回答

6

任何这样的“提示”都是编译器专用的。

作为示例,Visual C++允许您使用the __assume intrinsic提供此类提示。

(其他编译器也可以提供这样的内部函数,但我不与其他编译器不够熟悉而提供任何进一步的信息。如果你有兴趣,请咨询你的编译器的文档)。

+3

从我自己的谷歌搜索,海湾合作委员会4.5及以上可以传递这个信息,同样的语法也使用'#define __assume(cond)do {if(!(cond))__builtin_unreachable(); } while(0)' –

+0

@DrewDormann有趣。我认为最好是在Visual C++和gcc上定义一个宏#define ASSUME_THIS_THING(x)...,将其扩展为'__assume(x)'。最好不要用编译器保留的名称来定义你自己的宏(比如'__assume')。 –

+0

哇,太棒了。詹姆斯,小心把德鲁的信息合并到你的答案中?然后我会标记为已接受。 –

3

这不是标准,而是用gcc,有一个名为__builtin_expect的命令,其宏定义为likelyunlikely,这些命令可用于您的目的。例如,here举例说明在内核空间中使用它们,但是__builtin_expect是gcc扩展名,并且也可以在用户空间中使用(参见this question),即使没有定义likelyunlikely也没有定义。

+0

上面的评论中有一个错误:它应该是'__builtin_expect'。海湾合作委员会只是将期望作为一个提示:它不会避免不符合预期的情况。 –

+0

@MattG,是的,我不知道我是怎么写'buildtin'的! – Shahbaz

0

我不知道任何利用这些信息的C++编译技术,但我知道有各种各样的静态分析技术;常见的方式“告诉”的东西这些工具将通过assert S,例如:

assert(x > COMPILE_TIME_MIN); 
assert(x < COMPILE_TIME_MAX); 

通常这些工具还能够分析的东西,如“如果条件”本身,所以没有特别需要这样做。另外,如果范围非常小,也可以用较小尺寸的变量表示 - 例如,使用短或字符 - 并加入COMPILE_TIME_MIN。这可以帮助这些工具,但我不知道编译本身。

最后,和所有的优化方法一样,我建议首先分析一下你的代码,看看它是否真的成为瓶颈。另外,请记住,编译器专为优化“正常”代码而设计。 - 手工优化当然可以提供帮助,请谨慎操作。