【问题标题】:Templates and inlining- optimizing multiplication模板和内联优化乘法
【发布时间】:2013-03-10 01:24:34
【问题描述】:

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

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 ,除非 函数可以内联。

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

【问题讨论】:

  • 模板版本更快,因为您对其中一个操作数进行了硬编码。内联这两个版本将产生明显不同的代码,转储到汇编和对相同版本的检查可能会揭示这一点。由于它是二的幂,它会进一步增强吗?也许吧。

标签: c++ templates optimization inline-assembly


【解决方案1】:

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

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

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

a = Multiply(10,8);

可以替换为

a = 80;

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

【讨论】:

  • 事实上,当 both args 都是编译时常量时,它所做的优化不仅仅是上述完全消除乘法。例如,如果 one 参数是编译时常量,则在某些 x86 CPU 上,它实现了support.amd.com/us/Processor_TechDocs/… 的第 9.2 节中的完整表,以及其他简单分解的更多内容。
【解决方案2】:
a = Multiply(10,8);

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

a = 10 * 8;

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

如果你这样做了,那就不一样了:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2011-03-21
    • 1970-01-01
    • 2016-12-11
    • 2019-01-29
    • 2010-09-14
    相关资源
    最近更新 更多