C/C++ 是否提供最短执行时间的保证?

2024-06-22

为什么编译器似乎对不执行任何操作且不消除它们的循环很礼貌?

C 标准是否要求循环需要一些时间?

例如,以下代码:

void foo(void) {
    while(1) {
        for(int k = 0; k < 1000000000; ++k);
        printf("Foo\n");
    }
}

运行速度比这个慢:

void foo(void) {
    while(1) {
        for(int k = 0; k < 1000; ++k);
        printf("Foo\n");
    }
}

即使-O3优化级别。 我希望删除允许的空循环,从而在两个代码上获得相同的速度。

“花费的时间”是编译器应该保留的副作用吗?


不,花费的时间不算作受假设规则保护的可观察行为:

[C++14: 1.8/5]: 执行格式良好的程序的一致实现应产生与具有相同程序和相同输入的抽象机的相应实例的可能执行之一相同的可观察行为。然而,如果任何此类执行包含未定义的操作,则本国际标准对使用该输入执行该程序的实现没有任何要求(甚至不涉及第一个未定义操作之前的操作)。

[C++14: 1.5/8]:一致实施的最低要求是:

  • 对易失性对象的访问严格按照抽象机的规则进行评估。
  • 在程序终止时,写入文件的所有数据应与根据抽象语义执行程序可能产生的可能结果之一相同。
  • 交互设备的输入和输出动态应以这样的方式发生:在程序等待输入之前提示输出实际上被传递。交互设备的构成是由实现定义的。

这些统称为可观察的行为的程序。 [ Note:每个实现可以定义抽象语义和实际语义之间更严格的对应关系。——尾注]

这些循环可以合法地优化,事实上,在某些情况下,该标准使商榷尝试让这样做变得更加容易:

[C++14: 1.10/24]:该实现可能假设任何线程最终都会执行以下操作之一:

  • 终止,
  • 调用库 I/O 函数,
  • 访问或修改易失性对象,或者
  • 执行同步操作或原子操作。

[ Note:这是为了允许编译器进行转换,例如删除空循环,即使无法证明终止也是如此。——尾注]

事实上,您的编译器可能会“礼貌”地注意到循环的意图these程序似乎正在减慢重复文本输出的发出。 :)

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

C/C++ 是否提供最短执行时间的保证? 的相关文章

随机推荐

  • Hibernate 中的错误简单示例初级水平

    为了学习hibernate 我写了两个例子进行练习 但是 它们都存在相同的错误 如下所示 无法创建 sessionFactory 对象 java lang NoClassDefFoundError javax transaction Sys
  • 对于执行缓慢的查询,您最酷的 SQL 优化是什么?

    刚刚和我的一个同事说话 他迈着跳跃的步伐走向咖啡机 我问他 蜂群 行走是怎么回事 他说 我刚刚将两个小时的查询时间缩短到了 40 秒 感觉真好 他更改了一个使用游标的存储过程 并引入了一个临时表 该表是根据原始数据集重构的 我很快就会给他发
  • mechanize 的 UnicodeDecodeError 问题[重复]

    这个问题在这里已经有答案了 我通过 mechanize 从一个网站收到以下字符串 We x92ve 我知道 x92 代表 特点 我正在尝试将该字符串转换为 Unicode gt gt unicode We x92ve utf 8 Unico
  • 将 UML 转换为 OWL 本体

    我正在尝试基于以 XMI 格式呈现的不同 UML 文件资源开发 OWL 本体 现在通过互联网阅读了一段时间 似乎几乎所有可用的工具或方法都已经过时 即使尝试其中一些工具或方法 它们也无法提供预期的结果 由于这个本体在我们的项目中起着非常重要
  • 使用用户脚本自动选中复选框?

    某些网站 即 Steam 社区市场 要求用户手动选中特定复选框以执行重复操作 例如购买物品 我希望始终选中该复选框 URL http steamcommunity com market listings 730 USP S 20 7C 20
  • StructureMap单例

    这两个相等吗 1 var store new DocumentStore For
  • Python,使用subprocess.Popen进行linux命令行调用?我收到“[Errno 2] 没有这样的文件或目录”

    我正在尝试遵循我可以找到的有关 subprocess Popen 的信息 因为我想进行 linux 命令行调用 我正在尝试如下 但收到错误 Errno 2 没有这样的文件或目录 我没有尝试打开文件 所以我不理解这个错误 并且当我使用常规操作
  • 在 .NET 中将套接字发送/接收超时设置为小于 500 毫秒

    根据 MSDN 文档 不可能将 Socket SendTimeout 设置为小于 500ms 的值 http msdn microsoft com en us library system net sockets socket sendti
  • opencv潜在支持向量机[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想使用基于部件的模型进行对象分类
  • SQL Server相关问题

    我有这件事需要做 一些建议将不胜感激 我有一个包含一些电话的 SQL Server 表 对于每个电话 我都有开始和结束时间 我需要完成的任务是 一个存储过程 在一段时间内 假设以 x 间隔 5 小时 返回已连接呼叫的数量 Something
  • JSF,覆盖 HTTP 标头

    我强烈需要重写 JSF 2 0内容类型标头 默认是 Content Type application xhtml xml charset UTF 8 但是我需要 Content Type text html charset UTF 8 Th
  • 短语内容和流动内容有什么区别?

    我是 HTML 和 CSS 新手 我想知道流内容和短语内容之间的区别 除了 W3 官方文档之外MDN https developer mozilla org en US docs Web Guide HTML Content categor
  • Selenium 将文本粘贴到文本区域

    使用 Selenium 我想编辑textarea 呼唤textarea SendKeys My text 可以 但它是逐个字母地输入的 这对于较长的字符串来说显然相当慢 我发现的一种解决方法 http code google com p s
  • MATLAB:按扩展名从文件夹加载文件

    将具有相同扩展名的文件夹中的所有文件加载到 MATLAB 中的最简单方法是什么 我以前的解决方案 Will load a file if its filename is provided USAGE Best save data to a
  • 如何确定字符串是序列化对象/数组还是只是字符串?

    是否有一些可靠的方法来确定字符串变量是否只是一个字符串或序列化对象 数组的字符串表示形式 您可以致电unserialize string str http www php net manual en function unserialize
  • 如何从 CreateWindowEx() 窗口获取宽度和高度? C++

    我已经使用 CreateWindowEx 函数创建了一个窗口 现在如何从我创建的窗口中获取宽度和高度 这听起来很基本 但我找不到任何答案 这是必需的 因为窗口高度是根据 Windows 想要的创建方式自动创建的 语言 C 或 C Use 获
  • 如何解决“org.json.simple.JSONObject无法解析”?

    当我尝试通过 Tomcat 打开 jsp 时 我收到以下消息 无法解析 org json simple JSONObject 类型 它是从所需的 class 文件间接引用的 Ejercicio 类型中的 getJSONObject 方法引用
  • 如何将 Byte 数组转换为 Int 数组

    我正在使用以下方法读取文件 int len int new File args 0 length FileInputStream fis new FileInputStream args 0 byte buf new byte len fi
  • 加载模块一次,requirejs 带有示例

    我已经问过类似的问题 Requirejs Requirejs 加载每个模块一次 是什么意思 https stackoverflow com questions 18434356 requirejs what it means require
  • C/C++ 是否提供最短执行时间的保证?

    为什么编译器似乎对不执行任何操作且不消除它们的循环很礼貌 C 标准是否要求循环需要一些时间 例如 以下代码 void foo void while 1 for int k 0 k lt 1000000000 k printf Foo n 运