2

我不明白我遇到的这个例子:

int Multiply(int x, int m){
    return x * m;}

template<int m>
int MultiplyBy(int x){
    return x * m;}

int a,b;
a = Multiply(10,8);
b = MultiplyBy<8>(10);

在上面的示例中,模板函数比简单函数更快,因为编译器知道它可以通过使用移位操作来乘以 2 的幂。x*8 被替换为 x << ,这样更快。在简单函数的情况下,编译器不知道 m 的值,因此除非可以内联函数,否则无法进行优化。

据我了解,模板可以优化的原因是因为编译器在编译时知道参数 (8) 的值,而简单函数直到运行时才知道 x (或 m) 的值。那么内联简单函数将如何改变这一事实呢?内联不提供参数值的任何运行时知识?

4

2 回答 2

4

内联不提供参数值的任何运行时知识?

内联本身没有。但是,由于第二个参数是编译时常量,编译器可以将该常量传播到内联函数中。

由于第一个参数也是编译时常量,所以整个

a = Multiply(10,8);

可以替换为

a = 80;

事实上,这正是我的编译器(gcc 4.7.2)在我打开优化时所做的。

于 2013-03-20T18:51:12.090 回答
2
a = Multiply(10,8);

让我们手动内联函数调用:

a = 10 * 8;

现在,当然 8 在这里是编译时常量,因此编译器可以使用所描述的位移优化。但是,它可能会执行更好的优化,只需替换10 * 880. 编译器非常聪明——给定一个常量表达式,例如10 * 8,它们可以在编译时计算出结果。

如果你这样做了,那将是不同的:

int x;
std::cin >> x;
a = Multiply(10,x);

如果你Multiply在这里内联,你会得到:

int x;
std::cin >> x;
a = 10 * x;

编译器在编译时不知道 的值,x因此无法以相同的方式对其进行优化。

于 2013-03-20T18:55:23.370 回答