我使用 std::chrono c++ 库编写了下面的代码,我想做的是
将应用程序的 FPS
修复为 60 ,但我得到了 50 FPS
,这肯定不是性能问题
因为我什么也没计算。但这肯定是无效的用法或错误。
将TARGET_FPS
宏设置为我想要获取的目标FPS
,然后是控制台窗口
显示真正的实际 FPS ,以下几行显示我设置 TARGET_FPS
的值,每个值都与最终 FPS
相关联。
TARGET_FPS---->FPS
60----->50
90----->50
100----->100
1000----->100
10000----->100
whatever ----->100
即使我将 TARGET_FPS
定义为 1000000000,我也会得到 100 FPS
,即使我将其定义为 458 或任何大于 100 的值,我也会得到 100 FPS
作为输出。
#include <chrono> /// to use std::chrono namespace
#include <iostream> /// for console output
#include <thread> /// for std::this_thread::sleep_for()
#define TARGET_FPS 60// our target FPS
using frame_len_type = std::chrono::duration<float,std::ratio<1,TARGET_FPS>>; /// this is the duration that defines the length of a frame
using fsecond = std::chrono::duration<float>; /// this duration represents once second and uses 'float' type as internal representation
const frame_len_type target_frame_len(1); /// we will define this constant here , to represent on frame duration ( defined to avoid construction inside a loop )
void app_logic(){ /** ... All application logic goes here ... **/}
int main() /// our main function !
{
using sys_clock = std::chrono::system_clock; /// simplify the type name to make the code readable
sys_clock::time_point frame_begin,frame_end; /// we will use these time points to point to frame begin and end
while (true)
{
frame_begin = sys_clock::now(); /// there we go !
app_logic(); /// lets be logical here :)
frame_end = sys_clock::now(); /// we are done so quick !
std::this_thread::sleep_for( target_frame_len- (frame_end.time_since_epoch()-frame_begin.time_since_epoch()) ); /// we will take a rest that is equal to what we where supposed to take to finish the actual target frame length
std::cout<< fsecond(1) / ( sys_clock::now() - frame_begin) <<std::endl; /// this will show ass the current FPS
}
return 0; /// return to OS
} /// end of code
最佳答案
std::chrono 的计时分辨率取决于系统:
- 在 this answer对于另一个问题,您将找到一个代码片段来确定您的平台的大致计时分辨率。
- 在 Windows 7 上,default timer resolution is 15.6 ms
- 此外,windows API sleep C++标准库所依赖的,不保证线程在等待时间后立即恢复执行:
After the sleep interval has passed, the thread is ready to run. If you specify 0 milliseconds, the thread will relinquish the remainder of its time slice but remain ready. Note that a ready thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the sleep interval elapses.
- 无论您使用什么操作系统,C++ 标准库都不会为
sleep_for
提供更好的保证:
30.3.2/7: Effect: Blocks the calling thread for the relative timeout (...)
后果:
- 如果 FPS 设置为 60,则每 16.6 毫秒就会出现一帧。因此,假设您的
app_logic()
速度超快,您的线程将休眠至少 15.6 毫秒。如果逻辑执行时间为 1 毫秒,则帧速率恰好为 60 FPS。 但是,根据 API 文档,如果 [等待时间] 大于 1 个刻度但小于 2 个刻度,则等待时间可以是 1 到 2 个刻度之间的任意时间,因此平均 sleep 时间将在 15.6 到 31.2 毫秒之间,这反过来意味着您的 FPS 将在 60 到 32 FPS 之间。这解释了为什么您只能达到 50 FPS。
当您将 FPS 设置为 100 时,每 10 毫秒应该有一帧。这低于计时器的精度。可能根本就睡不着。如果没有其他线程准备运行,该函数将立即返回,以便您达到最大吞吐量。如果您设置更高的 FPS,您将处于完全相同的情况,因为预期等待时间将始终低于计时器精度。因此,结果不会改善。
关于c++ - 使用 std::chrono 库来调整应用程序 fps 但出现奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46258641/