Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 控帧方式从sleep+死循环修改为带误差修正的sleep #8

Merged
merged 4 commits into from
Mar 13, 2023

Conversation

Krimiston
Copy link
Collaborator

issue #7

@Krimiston Krimiston self-assigned this Feb 27, 2023
@gxm11
Copy link
Owner

gxm11 commented Feb 27, 2023

参考这篇博客:https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/

RGM当前的方式是precise sleep,之前讨论的WaitableTimer方案是timer sleep,pr的方案是system sleep。如博客展示的数据,system sleep精度差太多了(即使用的是high_resolution_clock + nanoseconds),pr里通过error 补偿,但因为精度较低导致每帧时间的浮动是±1ms,我觉得不合适。改成timer sleep + error调整如何,这个精度可以控制在0.1ms内。

关于代码本身:

  1. 用long double存counter这种语义上是整数的数据,是因为int64_t精度不够吗?long double具体的字节长度跟编译器有关,这可能导致别的问题。比如msvc上和double一样是8个字节(参见: https://godbolt.org/z/KzE4WT1W1 ),但是gcc是16个字节。
  2. 45行对counter的赋值应该移除,因为在33行已经操作过了。

@Krimiston
Copy link
Collaborator Author

读了博客很有感触。后续我会对 STL sleep_forWaitableTimer(Windows)、nanosleep(POSIX)针对实际精度做试验,试验完成后再确定方案做代码修改。
目前预想的修改方案是,改为 timer(Windows)/nanosleep(UNIX) + error 实现。

用 long double 存 error_counter 的原因:
error 需要有符号,而 counter 原本是 uint64 类型。error 选 int64 似乎不妥(可能会遇到溢出问题),我又不想用 int128(真的有吗?)类型,于是就用 long double 了。

@Krimiston
Copy link
Collaborator Author

已修改实现,见 issue #7

@gxm11
Copy link
Owner

gxm11 commented Mar 12, 2023

功能实现没有问题。有几处代码风格你看一下要不要改,不改的话也没关系,过两天我就会合并。

  1. 80行的 ULONGLONG 是不是就是 uint64_t?
  2. 82行和114行可以缩到预处理期分支if __WIN32里,这样也不需要在18-22行定义这两个宏了;
  3. 85-102行的do xxx while(0),用break跳出(假)循环,不如直接在99行后接else的写法,后面的代码也不多。

@Krimiston
Copy link
Collaborator Author

  1. 80行的 ULONGLONG 是不是就是 uint64_t?

此处为手误,已修改。ULONGLONG 应为 time_t

  1. 82行和114行可以缩到预处理期分支if __WIN32里,这样也不需要在18-22行定义这两个宏了;

设计如此。此宏定义是预留的,以防 POSIX 标准下也有类似 timeBeginPeriod 的计时器分辨率设置函数。(虽然似乎没有)

  1. 85-102行的do xxx while(0),用break跳出(假)循环,不如直接在99行后接else的写法,后面的代码也不多。

已修改。

Copy link
Owner

@gxm11 gxm11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

非常好工作,爱来自红宝石游戏现代。

@gxm11 gxm11 merged commit bd9a9c9 into gxm11:dev Mar 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants