【问题标题】:Pyglet uses too much cpuPyglet 使用过多的 cpu
【发布时间】:2012-11-12 23:08:32
【问题描述】:

我最近开始从 pygame 进入 pyglet 和 rabbyt,但我遇到了一些难题。

我创建了一个基本示例,其中一个 Sprite(在 pyglet.sprite.Sprite 中找到的类型)以每秒 60 帧的速度显示。问题是这个简单的程序不知何故占用了 50% 的 CPU 时间。我用在 rabbyt 库中找到的 sprite 类型重复了实验,结果相同。

我决定以每秒 60 帧的速度渲染 1000 个精灵,然后是 10000 个精灵,令我惊讶的是 CPU 使用率保持在 50%。唯一的问题是移动或动画精灵会导致轻微的卡顿。

最后,我尝试以每秒 360 帧的速度运行。结果相同,使用率为 50%。

这里是示例代码:

import pyglet
import rabbyt


def on_draw(dt):
    window.clear()
    spr.render()

global window
window = pyglet.window.Window(800, 600)
spr = rabbyt.Sprite('ship.png')
spr.x = 100
spr.y = 100
pyglet.clock.schedule_interval(on_draw, 1.0/60.0)


if __name__ == '__main__':
    pyglet.app.run()

我正在使用带有 ATI HD 3500 卡的 Core 2 Duo。

感谢任何建议/想法。

【问题讨论】:

  • ...您是否尝试过损坏位图?
  • 不,我实际上不知道损坏 blitting。你能给我指出一些关于它的文档吗?
  • 不是真的,但也不是很难;只需在精灵的旧位置绘制背景,然后在新位置绘制精灵。
  • 另外,global 声明不是必需的。无论如何,它不会在函数或方法之外做任何事情。
  • 我在几分钟前尝试了你的建议,我看到了同样的表现。

标签: python performance pyglet


【解决方案1】:

请注意,默认的 pyglet 事件处理程序将在每次清除事件队列时触发一个 'on_draw' 事件。

http://www.pyglet.org/doc/programming_guide/the_application_event_loop.html

pyglet 应用程序事件循环在窗口事件(例如鼠标和键盘输入)发生时分派它们,并在循环的每次迭代后将 on_draw 事件分派到每个窗口。

这意味着任何事件都可以触发重绘

因此,如果您正在移动鼠标或执行任何触发事件的操作,当它开始触发渲染调用时,您的速度会大大降低。

这也引起了问题,因为我正在执行自己的渲染调用,所以我会让两个缓冲区发生冲突,从而在屏幕上产生“幽灵”效果。我花了一段时间才意识到这是原因。

我猴子修补了事件循环以不这样做。 https://github.com/adamlwgriffiths/PyGLy/blob/master/pygly/monkey_patch.py

请注意,此修补后的事件循环将不再自行渲染,您必须手动翻转缓冲区或触发“on_draw”事件。

可能的情况是,虽然您已经以 60fps 的速度连接,但内部渲染循环正在以最大可能的速率滴答作响。

我不喜欢失去控制权的代码,因此我的补丁让我决定何时发生渲染事件。

【讨论】:

    【解决方案2】:

    嗯.. 如果有帮助,您可能想知道游戏运行的 fps:

    cldis = pyglet.clock.ClockDisplay()
    

    然后将其添加到您的 on_draw 函数中:

    cldis.draw()
    

    它以半透明的颜色在屏幕的左下角绘制当前 fps。

    【讨论】:

      【解决方案3】:

      我知道在 Pygame 中有内置的“时钟”。您可以使用 tick 方法限制游戏每秒循环的次数。在我的示例中,我设置了 30 FPS 的限制。这可以防止您的 CPU 处于持续需求状态。

      clock = pygame.time.Clock() 
      
      While 1:
      
          clock.tick(30) # Puts a limit of 30 frames per second on the loop
      

      在 pyglet 中似乎有类似的东西:

          pyglet.clock.schedule_interval(on_draw, 1.0/60.0)
          clock.set_fps_limit(60)
      

      希望有帮助!

      编辑:关于 fps 限制的文档:http://pyglet.org/doc/api/pyglet.clock-module.html#set_fps_limit

      【讨论】:

      • 您是否尝试过使用clock.set_fps_limit() 方法?它可能有助于提高性能。
      • 我已经用clock.schedule_interval安排了绘图间隔; clock.set_fps_limit(60) 没有改变任何东西(我也尝试了不同的帧值,比如 100 和 30) - 性能保持不变。
      猜你喜欢
      • 2011-04-03
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多