我正在使用PyBox2D(平台是Windows 10)的Python项目。据我了解,PyBox2D是Box2D的Python包装器,它是用C ++编写的,这似乎引起了我以前从未遇到过的问题。模拟通常运行得相当缓慢,但我最近发现,在将计算机从睡眠状态唤醒后约80秒,程序运行显着更快。然后,由于没有明显的原因,该程序减慢到通常的速度。无论是在计算机进入睡眠状态之前还是之后启动程序,都会发生加速。
我已经做了一些初步的基准测试,指出Box2D是个问题,但我不知道从哪里开始。首先,我检查了任务管理器。当程序运行缓慢时,Python正在使用大约8%的CPU。当程序快速运行时,它一致地使用25%(即完整核心)。然后,我通过cProfile运行它,看看哪些功能正在减慢速度。
以下是程序正常/缓慢运行时5个最耗时功能的统计数据:
ncalls tottime percall cumtime percall filename:lineno(function)
900 69.894 0.078 69.894 0.078 {built-in method b2World_Step}
180000 4.644 0.000 8.252 0.000 layer.py:61(__Activate)
601088 3.636 0.000 3.636 0.000 {method 'normal' of 'mtrand.RandomState' objects}
1980000 3.278 0.000 4.366 0.000 functions.py:3(Sigmoid)
90000 2.921 0.000 6.439 0.000 outputLayer.py:13(Activate)
以下是程序快速运行时的统计信息。
ncalls tottime percall cumtime percall filename:lineno(function)
900 7.127 0.008 7.127 0.008 {built-in method b2World_Step}
180000 4.429 0.000 7.914 0.000 layer.py:61(__Activate)
601072 3.778 0.000 3.778 0.000 {method 'normal' of 'mtrand.RandomState' objects}
1980000 3.191 0.000 4.205 0.000 functions.py:3(Sigmoid)
90000 2.861 0.000 6.265 0.000 outputLayer.py:13(Activate)
显然,Box2D的World_Step方法存在问题,但由于它是一个包装C ++代码的库,我无法弄清楚接下来要做什么。如果它应该是慢的,那我就没事了,但是通过唤醒计算机修复了某些错误,我想知道如何复制它而不实际让计算机进入睡眠状态。
以下是相关的代码:
simulator.py
from framework import (Framework, main)
from Box2D import *
class Simulator(Framework):
name = "Simulator"
experimentCount = 0
def __init__(self, showGraphics = True):
self.showGraphics = showGraphics
if(showGraphics):
super(Simulator, self).__init__()
else:
self.world = b2World(gravity=(0, -10), doSleep=True)
self.stepCount = 0
def Step(self, settings):
if(self.showGraphics):
super(Simulator, self).Step(settings)
else:
self.stepCount += 1
self.world.Step(1 / settings.hz, settings.velocityIterations, settings.positionIterations)
self.world.ClearForces()
if __name__ == "__main__":
main(Simulator)
main.py
from simulator import Simulator
import framework
import physicsSettings
from learningSettings import learningSettings
import cProfile
def test():
simulator = Simulator(False)
while(True):
simulator.Step(physicsSettings.fwSettings)
if(learningSettings.useGraphics):
framework.main(Simulator)
else:
cProfile.runctx('test()', globals(), locals(), 'profileResults1.pstats')