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

Does C/C++ offer any guarantee on minimal execution time?

本文关键字:任何保 执行时间 C++ 是否      更新时间:2023-10-16

为什么编译器似乎对什么都不做并且不消除它们的循环很礼貌?

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

示例,以下代码:

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

运行速度比这个慢:

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

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

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

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

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

[C++14: 1.5/8]: 对符合性实现的最低要求是:

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

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

这些循环可以在法律上被优化出来,事实上,在某些情况下,标准会故意尝试使这样做变得更加容易:

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

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

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

事实上,您的编译器可能会"礼貌地"注意到这些程序中循环的意图似乎是减慢重复文本输出的发射速度。 :)

您没有指定编译器,但让我们假设它是gcc

GCC 不会删除空循环,至少不会根据文档删除。它包含以下文本:

从历史上看,GCC 没有删除"空"循环,假设您在程序中放置一个循环的最可能原因是有延迟,因此删除它们不会使实际程序运行得更快。

但是,如果空循环

被优化程序"清空",即如果循环包含优化器可以在循环外移动的代码,并且生成的循环为空,则可以删除空循环。

从文档中不清楚在最新版本中是否仍然如此。该手册提到了"历史上",但没有具体说明原因。如果您使用有关确切平台和编译器的信息更新您的问题,也许可以给出更好的答案。

C 或 C++ 可执行文件没有最短执行时间,因为执行时间取决于许多特定于平台的问题,例如:

  1. 处理器时钟速率。
  2. 每条指令的时钟周期。
  3. 内部处理器执行优化。
  4. 中断。
  5. 处理器指令集/功能。

某些处理器支持乘法,而其他处理器则不支持。 不支持乘法的处理器执行程序所需的时间比具有乘法指令的进程要长。 与浮点数相同。

处理器的内部运行速度各不相同。 有一种常见的时间测量单位,称为"时钟周期"。 大多数处理器供应商以时钟周期指定指令的持续时间。 由于内部支持(例如缓存管理),此测量可能很困难。

某些处理器具有可以优化指令执行或指令模式的逻辑。 一种优化是分支预测

许多平台都有中断。 例如,可能存在"系统滴答"中断,它允许操作系统知道何时将执行切换到另一个程序。 有些不是那么周期性,例如当 I/O 发生时。 当程序中断时,无法保证最短执行时间。

声明最短执行时间会对 C 和C++语言可移植性造成严重破坏。 某些平台希望执行代码的速度快于最短时间。 其他平台可能无法实现最短的执行时间(但它们可以从像 C 这样的高级语言中受益)。

另外,时间将如何测量?

最短执行时间是否适用于延迟循环或轮询?

不,不能保证:(引自 N1570,5.1.2.3 程序执行)

1 本标准中的语义描述描述 抽象机器的行为,其中优化问题 无关紧要。

无论如何,C 标准只指定程序在抽象机器上执行时的行为,抽象机器可以有无限的内存和/或 CPU。