为什么编译器优化不生成 1..N 整数之和的循环?

2023-12-26

为了更好地理解编译器,特别是汇编语言,我一直在尝试一段简单的代码,其中第一个的总和N计算数字,这应该导致N(N+1)/2 or N(N-1)/2.

正如代码所示,有两个函数:

#include <cstdint>


// Once compiled with optimization, the generated assembly has a loop

uint64_t sum1( uint64_t n ) {  
    uint64_t sum = 0;
    for ( uint64_t j=0; j<=n; ++j ) {
        sum += j;
    }
    return sum;
}

// Once compiled with optimization, the generated assembly of the following has no loop

uint64_t sum2( uint64_t n ) {  
    uint64_t sum = 0;
    for ( uint64_t j=0; j<n; ++j ) {
        sum += j;
    }
    return sum;
}

在第一个函数中我循环O to N i.e. j<=n在第二个函数中我从O to N-1 i.e. j<n.

我的理解/观察:

  • 对于第一个函数sum1生成的程序集有一个循环 while 用于第二个函数sum2该组件显示没有循环。但是,一旦我删除编译器优化,即-O3,然后您终于可以在汇编中看到第二个函数的循环。

  • 要查看经过编译器优化生成的程序集,请参阅此优化 https://godbolt.org/z/8z8n5bKb7.

  • 要查看未经编译器优化生成的程序集,请参阅此未优化 https://godbolt.org/z/4bx8GadYP.

  • 编译器是x86-64 clang

Question: 为什么编译器优化不显示程序集中的其他循环?


这是因为你的编译器非常非常聪明,它知道从 0 到 n 的所有值的总和可以用一个简单的数学公式来计算,而不是循环。

然而,你的 C++ 编译器也发现这个数学公式不能用在<=版本,因为对于某些输入值,会触发错误,从而导致无限循环,因此所有的赌注都会被取消,并且编译器会完全按照给定的方式编译代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么编译器优化不生成 1..N 整数之和的循环? 的相关文章

随机推荐

  • 如何从函数返回 char 数组?

    我尝试过以下方法 char 10 testfunc char 10 str return str 最好作为输出参数 void testfunc char outStr char str 10 for int i 0 i lt 10 i ou
  • 从 Maven 中排除 TestNG 组

    我有一些缓慢的测试 这些测试依赖于我不想在每次使用 Maven 构建项目时运行的数据库 我已将 exceptGroups 元素添加到我的 pom 文件中 如下所述http maven apache org plugins maven sur
  • 黑莓上的应用程序详细信息

    我想开发一个应用程序来获取黑莓上其他已安装应用程序的详细信息 有没有可能 是的 您可以使用CodeModuleGroupManager loadAll http www blackberry com developers docs 6 0
  • 如何降级Webpack版本?

    我已经通过 NPM 在我的 ASP NET core Web 项目中安装了 Webpack 现在 webpack 的版本是 2 4 1 但是 我需要安装以下版本的 webpack 2 1 0 beta 25 我尝试使用以下命令 npm in
  • 如何在android中缓存listview数据?

    我有一个包含 100 行的列表视图 这是我第一次从 Web 服务加载所有数据 我想缓存该数据 这样如果我打开该页面 我应该从缓存而不是从 Web 服务获取它 我怎样才能做到这一点 如果您的数据足够简单 只需将它们存储在数组中并使用类似的东西
  • java JGraphx 保存为图像

    有谁知道如何将 JGraphx 导出为任何格式的图像 如果没有 那么有人知道任何其他java库可以让我创建简单的图表然后将其保存为图像吗 对于 PNG 格式应该这样做 BufferedImage image mxCellRenderer c
  • Vapor Xcode 项目中两个几乎相同的目标

    我想配置 Package swift 以便一个目标成为另一个目标的扩展 它们都应该共享一个文件夹中的相同代码 但对于 扩展 版本 还有一个额外的子文件夹 但我尝试使用的配置path因 重叠源 错误而失败 那么 如何使两个目标具有相同的源文件
  • 更改行 extjs4 的背景颜色

    我有一个名为 grid 的网格 并且加载时有行被插入到网格中 有些行将显示为绿色 则表示已成功输入行 而背景颜色为红色的行将出现错误 我让它在某个时候工作 但错误行将被添加到网格中 其背景色为红色 然后 当我尝试添加新行以输入新数据时 所有
  • 如何使 AuthorizeEndpointPath 在 ASP.NET Oauth 2.0 框架中工作

    我目前有一个网站 我正在尝试实现 OAuth 服务器框架 该网站目前是 Web Forms 不是 MVC 和 Web API 2 的组合 出于我想要做的目的 我们无法更改系统的整体架构 到目前为止 我通过 Web API 使用 OAuth
  • RXJava 如何尝试在 x 时间后获取下一个

    我想每 x 秒使用改造调用一次 Web 服务 直到引发 y 条件 我想跑OrderApi getx 秒后直到响应为空 public class OrderApi public static Observable
  • Notepad++搜索和替换:删除每行“/”后面的所有内容

    我有一个纯文本文件 内容如下 pre ra RN pre rie Z pre r c zZ pre u c 问 如何删除之后的所有字符串 Notepad 中每一行的符号 期望的输出 pre ra pre rie pre r c pre u
  • Kubernetes PetSet DNS 不工作

    我有一个 Kubernetes PetSet 名称为 elasticsearch和服务名称 es 它确实创建了 pod 并且正如预期的那样 它们的名称如下elasticsearch 0 and elasticsearch 1 但是 DNS
  • 在 F# 中模拟 Prolog 回溯

    我目前正在参与一个项目 开发一个应用程序 该应用程序能够考虑一组节点和连接 并找到两个节点 在允许的连接上 之间的最短路径 一个常见且众所周知的问题 好吧 我实际上不必从零开始构建应用程序 而只需要 转换 f 中的 Prolog 预先存在的
  • 如何使用动态创建的选项卡和 for 循环显示 ggplotly 绘图?

    我有 R markdown 文档 我想动态创建其中包含 ggplotly 图形的选项卡 output html document r setup include FALSE knitr opts chunk set echo TRUE r
  • 保存并共享对 Vagrant box 所做的更改

    我从 www vagrantbox es 设置了一个 Ubuntu 13 04 盒子 发布我对盒子进行了更改 安装了 ruby rails git mysql ngnix 等 如何与其他人共享修改后的盒子 进行更改后 使用vagrant p
  • 如何将背景图片放入文本框内

    有谁知道如何将背景图像放入文本框内 我想做的是 当我单击文本框时 它会用图像更改背景 有人知道该怎么做吗 我当前的代码无法工作
  • 绝对路径与相对路径

    如果我使用绝对路径 我无法将整个目录移动到新位置 如果我使用相对路径 我无法将单个文件移动到新位置 这里有什么解决办法呢 您是否设置了一个保存根路径的配置文件并从那里开始 或者您是否有这样的规则 永远不要移动文件 我在一些项目中看到人们使用
  • CSS 文本边框? [复制]

    这个问题在这里已经有答案了 可能的重复 CSS 字体边框 https stackoverflow com questions 2570972 css font border 是否可以设置 文本边框 用CSS 最好是有多个边界 像图像上的东西
  • 增加 Parallel.For 中运行线程的数量

    我刚刚做了一个多线程示例这个链接 https stackoverflow com questions 14869651 number of threads being used during parallel foreach像下面这样 Co
  • 为什么编译器优化不生成 1..N 整数之和的循环?

    为了更好地理解编译器 特别是汇编语言 我一直在尝试一段简单的代码 其中第一个的总和N计算数字 这应该导致N N 1 2 or N N 1 2 正如代码所示 有两个函数 include