睡眠/等待,不消耗CPU

2023-12-14

所以我正在将这个智能手机应用程序模拟到 Windows。这是一个运行其逻辑并绘制方法的游戏1/60速度。以毫秒为单位,这是16.6667

我已经实现了这个游戏循环:

    private const double UPDATE_RATE = 1000d / 60d;

    private void GameLoop()
    {
        double startTime;
        while (GetStatus() != GameStatus.NotConnected)
        {
            startTime = Program.TimeInMillis;
            //Update Logic
            while (Program.TimeInMillis - startTime <= UPDATE_RATE)
            {
                //Thread.Yield(); it consumed CPU before adding this too, adding this had no effect
                Thread.Sleep(TimeSpan.FromTicks(1));//don't eat my cpu
            }
        }
        Debug.WriteLine("GameLoop shutdown");
    }

Program.TimeInMillis来自一个NanoStopwatch类,返回以毫秒为单位的时间double。这很有用,因为这个游戏循环必须非常准确才能使一切正常运行。

您可能知道,Thread.Sleep这里会消耗大量的CPU。可能是因为需要int millis这将转换我的TimeSpan到 0 毫秒。

我最近遇到了一个叫做WaitHandle,但我看到的一切都使用int millis。我真的需要使其准确,所以我实际上需要double millis or microseconds/nanoseconds.

C# 中有什么东西可以让我Waitx 微秒量。我不介意自己创造一些东西(就像我为NanoStopwatch),但我需要指出正确的方向。网上找了很多,不过都是用的int millis这对我来说不够准确。

我进行了一些测试,改变了Sleep使用类似的东西:UPDATE_RATE - (Program.TimeInMillis - startTime)这并不能让我的游戏循环准确。

我希望一切都足够清楚,如果您需要更多信息,请发表评论。

tl;dr - 有什么方法可以让线程等待一段时间microseconds/nanoseconds in C#?我的游戏循环需要准确,而毫秒对我来说还不够准确。

提前致谢!


您需要硬件支持才能实现这种精度。产生一个信号打断并触发代码来完成工作。在 Windows 中,这种信号有两个明显的候选者。

第一个是 VSYNC 中断,视频设备驱动程序的实现细节。它发生在显示器刷新率下,对于 LCD 显示器,通常为 60 赫兹。当然,这正是您所要求的,并非巧合。大多数程序员使用 DirectX 来实现游戏图形,你要求它使用带有D3DPRESENT 设置。否则很不清楚为什么你不从问题中使用它,而是你应该追求的解决方案。

第二个是时钟中断。这就是你所抱怨的。在 Windows 上,最重要的是唤醒线程调度程序并让代码运行的信号。它直接负责Thread.Sleep()的准确性。睡眠的代码无法再次开始运行,直到时钟中断发生并且调度程序将线程恢复到活动状态。没有其他办法可以做到这一点,处理器通过 HLT 指令物理关闭,不消耗功率,只能通过中断唤醒。默认情况下,时钟中断每秒滴答 64 次。每 15.625 毫秒一次。它往往会被驱动程序等修改,他们经常将其重新编程为 10 毫秒。提供免费软件并持有其股份的公司让自己的产品看起来不错使其低至 1 毫秒。

如果由于某种原因您无法驯服 DirectX,这也是您需要做的。平沃克时间开始期间(1)获得 1 毫秒的精度。从技术上讲,您可以使用 NtSetTimerResolution() 将时间低至 500 微秒,但这只是表盘所能达到的最低值。请记住,您无法始终如一地维持这样的速率,线程调度量子、垃圾收集暂停、硬分页错误和以实时优先级运行代码的令人讨厌的设备驱动程序花费的时间比这要长得多。

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

睡眠/等待,不消耗CPU 的相关文章

随机推荐

  • conda 更新 CondaHTTPError:HTTP 无

    跑步中途Conda Update all 更新停滞了 多个软件包已更新 现在 当我跑步时conda update all or conda update conda 我得到这样的回应 C Users AppData Local Contin
  • 使用 Indy 10 和 DELPHI 评估电子邮件

    我使用以下代码来评估消息 使用 INDY 10 组件收到的电子邮件消息的内容 正文 行 function LinesFromMsg aMsg TIdMessage TStrings var i Integer begin for i 0 t
  • 关于Java基本类型方法的问题

    我对 Java 中的原始类型以及将一种类型转换为另一种类型的方法感到困惑 比如说 如果我有一个整数并且想将其转换为字符串 我需要使用 Integer 或 String 的静态方法 例如 String valueOf some integer
  • Ansible 中的列表按自然字母数字顺序排序

    有没有办法以自然的方式对 Ansible 或 Jinja 中的列表进行排序 例如 这是列表 test test123 test12 test5 test1234test test22te 我需要它来考虑整个数字而不是单个数字 所以test1
  • 对于简单且可变的产品,以特定的 html 结构显示一些数据

    在 WooCommerce 中 我想创建一个函数 为每个变体或可变产品输出一个简单的数据 列表 或者 如果是一个简单的产品 那么该产品本身的细节 我需要为每个项目添加的详细信息是 regular price size attribute 用
  • 多个 BindingContext 在同一内容页上,两个不同的视图?

    我有一个 ContentPage 上面有两个 ContentView 我想将每个 ContentView 的绑定上下文设置为各自的 ViewModel 这是我对它们组合在一起的一个大型 ViewModel 的首选灵魂 MainPage
  • 如何在 JavaScript 中合并 TypedArray?

    我想合并多个数组缓冲区来创建一个 Blob 然而 如你所知 类型数组没有 推 或有用的方法 E g var a new Int8Array 1 2 3 var b new Int8Array 4 5 6 结果 我想得到 1 2 3 4 5
  • 重新安装 ruby​​gems

    如何重新安装 RubyGems 如中所述没有要加载的文件 rubygems LoadError 运行 Mac OS X 10 8 2 直接从源下载 我在尝试获取时遇到了很大的麻烦gem update system or gem instal
  • React Router Dom,useNavigate 未重定向到正确的 url 路径

    在较旧的 React Router Dom 版本中 如果用户登录 我可以使用此代码进行重定向 history push login redirect shipping Now in v6 我正在使用useNavigate函数而不是histo
  • 如何删除 MySQL 数据库中的重复行? (保留主 ID 最低的那个)

    假设我想首先选择 download link 相同的行 然后 我想保留具有最低主 ID 的那个 并丢弃其余的 有没有简单的 SQL 语句可以实现这一点 这行得通吗 delete from mytable where id not in se
  • 超出 LDAPException 大小限制

    我正在使用 unboundid ldap sdk 来执行 ldap 查询 我在运行 ldap 搜索查询时遇到一个奇怪的问题 当我对包含 50k 条目的组运行查询时 出现异常 我的例外 LDAPException resultCode 4 s
  • 脚本中的双连字符使 Firefox 渲染异常

    当我在纯 html 页面的 部分中有上述行时 Firefox 3 5 5 会将尾随 gt 呈现为文本 如果我将 c 更改为 c 则不会 有什么想法吗 由于经过处理的非常大的脚本 我的页面上出现了一个工件 我可以将语句更改为 c 1 并暂时避
  • AS3:获取 Matrix 对象的比例

    最常见的问题是如何缩放 DisplayObject 答案通常是使用 Matrix 我的问题是 如何获取矩阵的比例 scaleX 和scaleY 有一个 Matrix scale 方法来设置scaleX和scaleY 但它不返回值 并且不存在
  • 如何以编程方式确定 iOS 中的默认电子邮件帐户/地址?

    在 iOS 设备上 一次可以配置多个电子邮件帐户 在 设置 应用中 用户可以选择默认电子邮件帐户 邮件 gt 邮件 默认帐户 此默认帐户是通过 MFMailComposeViewController 发送电子邮件时的 发件人 地址 是否有
  • Python 中 dir() 和 __dict__ 最大的区别是什么

    class C object def f self print self dict print dir self c C c f output class delattr f 为什么 self dict 中没有 f dir 所做的不仅仅是仰
  • 将 JPanel 变成 JOptionPane.OK_OPTION

    目前我有一个扩展 JPanel 的类 基本上显示有关传递到其构造函数的对象的一些信息 屏幕上有各种标签和图像图标 并且有一个 BorderLayout 设置 当用户左键单击主 GUI 中的 ImageIcon 并显示在屏幕上时 会触发此面板
  • .NET 中集合的内存分配

    这可能是一个骗局 我没有找到足够的信息 我正在讨论 Net 中集合的内存分配 集合中分配的元素的内存在哪里 List
  • 如何使用 Bootstrap 在 Django 中自定义复选框和单选框?

    我正在尝试使用 bootstrap 类自定义 Django 中的复选框和单选按钮 然而 这并没有奏效 我已经尝试在 forms py 中插入引导类widgets and attrs custom control custom radio c
  • Sparql 使用变量绑定计数结果

    有什么办法可以bind的结果count到一个变量 我尝试了以下方法 不起作用 SELECT totalSubject WHERE s p o BIND COUNT s AS totalSubject COUNT is an 总计的函数 只能
  • 睡眠/等待,不消耗CPU

    所以我正在将这个智能手机应用程序模拟到 Windows 这是一个运行其逻辑并绘制方法的游戏1 60速度 以毫秒为单位 这是16 6667 我已经实现了这个游戏循环 private const double UPDATE RATE 1000d