当前位置: 首页 > 知识库问答 >
问题:

现代编译器优化1和-1的乘法吗

史逸春
2023-03-14

如果我写

template<int sign>
inline int add_sign(int x) {
    return sign * x;
}

template int add_sign<-1>(int x);
template int add_sign<1>(int x);

大多数C编译器是否足够聪明,能够将1或-1的乘法优化成更快的运算(无操作或求反)?

共有3个答案

殳勇
2023-03-14

虽然在这种情况下编译器会为您进行优化,但在更复杂的情况下,可能需要为不同的模板参数编写不同的优化代码。因此,您可以使用模板专门化来做到这一点:

template<int sign>
inline int add_sign(int x);

template<>
inline int add_sign<-1>(int x) {
    return -x;
}

template<>
inline int add_sign<1>(int x) {
    return x;
}

有了这样一个完全专业化的函数,你不需要为它编写显式实例化。

颛孙俊
2023-03-14

对于<code>g</code>,请使用<code>g-S Foo。cc查看汇编程序并确定模板是否已优化。对于clang,请看一下这个问题。对于Visual Studio,请看一看这个问题。

年业
2023-03-14

是的。这是称为算术局部优化的一类简单优化的一部分。例如,1 * x 可以静态简化为 x,同样,-1 * x 可以简化为 -x生产编译器都这样做,并且还有更复杂的优化。

 类似资料:
  • 根据这个问题,浮点除法与浮点乘法。由于某些原因,除法比乘法慢。 如果可能的话,编译器通常会用乘法代替除法吗? 例如: 会是: 如果它被认为是编译器可靠的问题,我使用的是VS2013默认编译器。但是,如果我得到一个通用的答案就好了(这种优化的理论有效性)

  • 有问题的代码如下: 编译器会优化它吗?根据C-Standard(如果我理解正确的话),第二个操作数必须提升为;因此乘法必须使用FPU(或fp仿真)完成。 从理论上讲,该操作可以在正常的硬件寄存器中完成,只需添加一个即时的(并且可能是溢出检查)。是否允许编译器执行此优化?是否有已知的编译器这样做?如果是这样,他们是否也会识别该表达式 这是避免有关隐式转换的静态代码检查器警告所必需的? 补充一下:我知

  • 如果关闭了编译器优化(gcc-o0...),那么说'volatile'关键字没有区别是可以的吗? 我制作了一些示例“C”程序,并且仅当打开编译器优化时,才在生成的汇编代码中看到易失性和非易失性之间的区别,即((gcc-o1....)。

  • 主要内容:1.避免使用select *,2.用union all代替union,3.小表驱动大表,4.批量操作,5.多用limit,6.in内东西过多,7.增量查询,8.高效的分页1.避免使用select * 因为select * 查出来的数据是全部的数据,需要的数据包含其中,但是也有不需要的数据,效率低 select*不走索引,会出现大量的回表操作,而从导致查询sql的性能很低。 sql语句查询时,只查需要用到的列,多余的列根本无需查出来。 2.用union all代替union sql语句使

  • 我最近在部署到我们的共享主机时遇到了问题。从 Visual Studio 通过 Web 部署进行部署时,99% 的时间我在登录后在登录页面或主页上收到此错误。有时我可能会点击几下不同的部分,然后它就会击中。它通常会在几分钟到90分钟后消失。 运行Windows Server 2012 R2 Standard、IIS8和.NET 4.5的Web主机。 Web主机建议我需要使用Visual Studi

  • 问题内容: 假设我在C代码中有类似的内容。我知道您可以使用a 代替,以使编译器不对其进行编译,但是出于好奇,我问编译器是否也可以解决此问题。 我认为这对于Java编译器来说更为重要,因为它不支持。 问题答案: 在Java中,if内的代码甚至都不是已编译代码的一部分。它必须编译,但不会写入已编译的字节码。它实际上取决于编译器,但我不知道没有对它进行优化的编译器。规则在JLS中定义: 优化的编译器可能