While scripting in python, I noticed that the task manager takes a huge hit on frame rate. I currently have a very simple script with only one task loop, and when I comment that task out, Panda is pumping out over 900fps. But when I start the task, even with nothing in it, it shoots down to about 86~88fps. Why is it that tasks use up so much speed?
It means your task is consuming 10 ms. That does seem a lot, but you canât blame the task manager itself, because even before you start any of your tasks, the task manager is handling about 10 default tasks, including the task to actually render frames.
If it can handle 10 tasks in 900fps (about 1 ms), but you add 1 task and it drops to 90fps (about 11 ms), somewhere in that 1 task you just added 10 ms.
So, what is your task function doing, even with ânothing in itâ, to consume 10 ms?
Note that you can prove your task timings by putting:
task-timer-verbose 1
in your Config.prc file, and then printing taskMgr, which lists all of the tasks and how much time theyâre tasking.
David
Iâm not sure if I added the taskMgr print to the right spot⌠Here is the code:
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import *
from direct.task import Task
import math
import DataLoader
class Player():
def __init__(self):
self.player = DataLoader.DataLoader().loadPlayer('Objects/teapot.egg.pz')
''' Set up camera behind player '''
camera.wrtReparentTo(self.player)
camera.setPos(self.player.getX(),-20,8)
camera.lookAt(self.player)
camera.setP(camera.getP()+10)
''' Set up collision ray to snap to ground '''
self.myTraverser = CollisionTraverser('selectable')
self.myHandler = CollisionHandlerQueue()
pPos = self.player.getPos()
pickerNode=CollisionNode('mouseRay')
pickerNP = self.player.attachNewNode(pickerNode)
pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
self.pickerRay=CollisionRay(pPos[0], pPos[1], pPos[2], 0, 0, -1)
pickerNode.addSolid(self.pickerRay)
self.myTraverser.addCollider(pickerNP, self.myHandler)
pickerNP.show()
self.linV = 0.0
self.maxV = 0.2
self.accel = 1.01
self.groundZ = self.player.getZ()
self.groundNor = 0.0,0.0,0.0
#taskMgr.add(self.updatePlayer, "updatePlayer") #Drops framerate 950->88
print taskMgr
def updatePlayer(self,task):
'''
rayPos = self.player.getPos(self.player)
rayPos = rayPos[0]+0.1,rayPos[1]+0.1,rayPos[2]+0.1
self.pickerRay.setOrigin(*rayPos)
self.myTraverser.traverse(render)
if self.myHandler.getNumEntries() > 0:
self.myHandler.sortEntries()
pickedObj=self.myHandler.getEntry(0).getIntoNodePath()
pickedObj=pickedObj.findNetTag('ground')
if not pickedObj.isEmpty():
self.groundZ = self.myHandler.getEntry(0).getSurfacePoint(self.player)[2]
self.groundNor = self.myHandler.getEntry(0).getSurfaceNormal(self.player)
key = self.keyState()
if key[0] != 0:
if self.linV < self.maxV:
self.linV += key[0] * globalClock.getDt() * self.accel
else:
if self.linV < 0.02:
self.linV = 0
self.linV = self.linV * (globalClock.getDt() * self.accel) #I think I need accel to approach 0..
angV = 60*key[1]*globalClock.getDt()
self.player.setPos(self.player,
0,
self.linV,
self.groundZ)
self.player.setHpr(self.player,
angV,
-1*self.groundNor[1],
0)
'''
return task.cont
def keyState(self):
keyUp = base.mouseWatcherNode.isButtonDown(KeyboardButton.up())
keyDown = base.mouseWatcherNode.isButtonDown(KeyboardButton.down())
keyLeft = base.mouseWatcherNode.isButtonDown(KeyboardButton.left())
keyRight = base.mouseWatcherNode.isButtonDown(KeyboardButton.right())
keyAction= base.mouseWatcherNode.isButtonDown(KeyboardButton.space())
forward = keyUp + -keyDown
turn = keyLeft + -keyRight
return forward,turn,keyAction
Task enabled with all commands commented out: (playerUpdate)
The taskMgr is handling:
taskList dt(ms) avg max priority
-------------------------------------------------------------------------
-------------------------------------------------------------------------
pendingTasks
-------------------------------------------------------------------------
(P)eventManager 0.00
(P)updatePlayer 0.00
(P)shadowCollisionLoop 44.00
(P)resetPrevTransform -51.00
(P)dataLoop -50.00
(P)igLoop 50.00
(P)ivalLoop 20.00
(P)doLaterProcessor -10.00
(P)audioLoop 60.00
(P)collisionLoop 30.00
-------------------------------------------------------------------------
total 0.00 0.00
-------------------------------------------------------------------------
doLaterList waitTime(s)
-------------------------------------------------------------------------
-------------------------------------------------------------------------
End of taskMgr info
TaskMgr.add commented out:
The taskMgr is handling:
taskList dt(ms) avg max priority
-------------------------------------------------------------------------
-------------------------------------------------------------------------
pendingTasks
-------------------------------------------------------------------------
(P)eventManager 0.00
(P)shadowCollisionLoop 44.00
(P)resetPrevTransform -51.00
(P)dataLoop -50.00
(P)igLoop 50.00
(P)ivalLoop 20.00
(P)doLaterProcessor -10.00
(P)audioLoop 60.00
(P)collisionLoop 30.00
-------------------------------------------------------------------------
total 0.00 0.00
-------------------------------------------------------------------------
doLaterList waitTime(s)
-------------------------------------------------------------------------
-------------------------------------------------------------------------
End of taskMgr info
Well, you do have to let some frames go by before you get any meaningful statistics out of printing taskMgr, of course. Ideally, youâre running the Python script interactively, so you just break into the script after a few seconds and print the taskMgr by hand. If your editor wonât let you break into the script, then you can do it with a doMethodLater or something.
But I donât see any frame rate drop when I try your code.
David
On the other hand, I could easily believe your taskâwithout the commenting-out quotesâwould consume 10ms. Youâre doing a lot of work in that task function, including calling the collision traverser.
Are you sure you were running the quoted-out version of this code when you saw the frame rate drop, and that you werenât still accidentally running the whole task function?
David
I was probably doing something stupid like running the script without saving changes, because itâs working nowâŚ
It looks like all I need to do is find a less expensive way to project an object onto the surface of another.
I appreciate your help as always, drwr!