std::chrono::high_resolution_clock 基于帧定时器
std::chrono::high_resolution_clock based frame timer
多年来我一直在为帧定时器使用以下时钟定义:
using frame_clock = std::conditional_t<
std::chrono::high_resolution_clock::is_steady,
std::chrono::high_resolution_clock,
std::chrono::steady_clock>;
换句话说,我想要一个使用尽可能高的分辨率定义的时钟,但它必须单调递增。请注意,MSVC 当前使用以下别名来定义 std::chrono::high_resolution_clock
:
using high_resolution_clock = steady_clock;
因此,在 MSVC 上,我定义的别名将只使用 std::chrono::steady_clock
。这对于 libstdc++ 和 libc++ 不一定正确,因此使用别名。
最近,我在这里偶然发现了一个脚注:https://en.cppreference.com/w/cpp/chrono/high_resolution_clock
请注意,cppreference 明确不鼓励使用 std::chrono::high_resolution_clock
。他们的理由是时钟因实施而异……但 std::chrono::steady_clock
和 std::chrono::system_clock
不也是如此吗?例如,我找不到任何保证时钟之间的时钟周期必须以特定单位表示的东西。事实上,我的理解是设计。
我的问题是,在使用 std::chrono::high_resolution_clock
这么多年(用于帧计时器和基准测试)之后,我是否应该比现在更担心?即使在这个网站上,我也看到许多使用 std::chrono::high_resolution_clock
的建议,不管这个脚注怎么说。任何关于这种差异的进一步见解,或这可能导致问题的示例,将不胜感激。
你读到的基本上是我在过去几年中一直给出的建议。
并不是说 high_resolution_clock
很危险。只是比较没用。这是因为它始终是 system_clock
或 steady_clock
的别名。因此,您不妨选择 system_clock
或 steady_clock
,这样您就知道您得到的是哪一个。
steady_clock
总是有is_steady == true
。这是一个要求。另外 system_clock
never 有 is_steady == true
。这实际上不是必需的,但除非您的计算机有一个保持 完美 时间的时钟,否则它需要偶尔调整以将其设置为正确的时间。而一个可以调整的时钟必须有is_steady == false
.
您的 frame_clock
别名只是一种奇特的说法:
using frame_clock = std::chrono::steady_clock;
出于实际目的,您只有 3 个选择:
- 要获得实时性,您唯一的选择是
std::system_clock
(如果您想留在 C++ 中,OS 级例程确实存在)
- 对于测量间隔,如果你想留在 C++ 中,你必须使用
std::steady_clock
。没有实现可以拥有比 std::steady_clock
分辨率更高的稳定时钟
- 如果您急于牺牲 C++ 一致性,则上述方法的可行替代方法是直接使用 TSC 计数器。这是人们所能看到的最高分辨率,也是最快的使用方法。缺点是,如果您想测量时间单位而不是周期,则必须使用 CPU 周期率将周期转换为秒。
是的,你应该担心。 high_resolution_clock
是实现定义的。不要让工具pick,直接用steady_clock
就可以了
Howard Hinnant 写了一篇很棒的文章 and 。
和以前一样,坚持直接使用 std::chrono::steady_clock
而不是让实现选择。
多年来我一直在为帧定时器使用以下时钟定义:
using frame_clock = std::conditional_t<
std::chrono::high_resolution_clock::is_steady,
std::chrono::high_resolution_clock,
std::chrono::steady_clock>;
换句话说,我想要一个使用尽可能高的分辨率定义的时钟,但它必须单调递增。请注意,MSVC 当前使用以下别名来定义 std::chrono::high_resolution_clock
:
using high_resolution_clock = steady_clock;
因此,在 MSVC 上,我定义的别名将只使用 std::chrono::steady_clock
。这对于 libstdc++ 和 libc++ 不一定正确,因此使用别名。
最近,我在这里偶然发现了一个脚注:https://en.cppreference.com/w/cpp/chrono/high_resolution_clock
请注意,cppreference 明确不鼓励使用 std::chrono::high_resolution_clock
。他们的理由是时钟因实施而异……但 std::chrono::steady_clock
和 std::chrono::system_clock
不也是如此吗?例如,我找不到任何保证时钟之间的时钟周期必须以特定单位表示的东西。事实上,我的理解是设计。
我的问题是,在使用 std::chrono::high_resolution_clock
这么多年(用于帧计时器和基准测试)之后,我是否应该比现在更担心?即使在这个网站上,我也看到许多使用 std::chrono::high_resolution_clock
的建议,不管这个脚注怎么说。任何关于这种差异的进一步见解,或这可能导致问题的示例,将不胜感激。
你读到的基本上是我在过去几年中一直给出的建议。
并不是说 high_resolution_clock
很危险。只是比较没用。这是因为它始终是 system_clock
或 steady_clock
的别名。因此,您不妨选择 system_clock
或 steady_clock
,这样您就知道您得到的是哪一个。
steady_clock
总是有is_steady == true
。这是一个要求。另外 system_clock
never 有 is_steady == true
。这实际上不是必需的,但除非您的计算机有一个保持 完美 时间的时钟,否则它需要偶尔调整以将其设置为正确的时间。而一个可以调整的时钟必须有is_steady == false
.
您的 frame_clock
别名只是一种奇特的说法:
using frame_clock = std::chrono::steady_clock;
出于实际目的,您只有 3 个选择:
- 要获得实时性,您唯一的选择是
std::system_clock
(如果您想留在 C++ 中,OS 级例程确实存在) - 对于测量间隔,如果你想留在 C++ 中,你必须使用
std::steady_clock
。没有实现可以拥有比std::steady_clock
分辨率更高的稳定时钟
- 如果您急于牺牲 C++ 一致性,则上述方法的可行替代方法是直接使用 TSC 计数器。这是人们所能看到的最高分辨率,也是最快的使用方法。缺点是,如果您想测量时间单位而不是周期,则必须使用 CPU 周期率将周期转换为秒。
是的,你应该担心。 high_resolution_clock
是实现定义的。不要让工具pick,直接用steady_clock
就可以了
Howard Hinnant 写了一篇很棒的文章
和以前一样,坚持直接使用 std::chrono::steady_clock
而不是让实现选择。