About the number of cores used

Hi everyone…I have a question that I’m guessing it may or may not have an answer.

I’m doing a rudimentary version of guitar hero with a portuguese song…thing is…it’s to be played in 4 screens at once, each instrument in one screen…my problem: throughout the gameplay, it gets really slow and i checked the cpu performance (i7 2600k) and only one of the cores is being used @ 100%, any way to go around this?

Thanks,

António

The upcoming 1.8.0 release of Panda3D will provide an easy way to utilise multiple cores efficiently.

Read this blog post for more information:
panda3d.org/blog/?p=206

Thank you for the reference…but at this moment, is there any immediate solution other than making my program lighter?

The project is due december :X

Write better code. :wink:

What is the resolution of the monitors?

1024*768

Thing is…what’s making it slow is hardcoding the musical instruments the player has to tap (pretty much like guitar hero)…should i go random?

example

	[1.4,BLUE_NOTE ],
	[1.4,RED_NOTE ],
	[1.4,YELLOW_NOTE ],
	[1.4,GREEN_NOTE ],
	[1.7,RED_NOTE ],
	[1.8,RED_NOTE ],
	[1.9,YELLOW_NOTE ],
	[2.0,GREEN_NOTE ],
	[2.1,GREEN_NOTE ],
	[2.2,BLUE_NOTE ],
	[2.3,YELLOW_NOTE ],
	[2.4,RED_NOTE ],
	[2.5,GREEN_NOTE ],
	[3.0,BLUE_NOTE ],
	[4.5,GREEN_NOTE ],
	[5.1,GREEN_NOTE ],
	[5.2,BLUE_NOTE ],
	[5.3,YELLOW_NOTE ],
	[5.4,RED_NOTE ],
	[5.4,BLUE_NOTE ],
	[5.4,RED_NOTE ],
	[6.4,YELLOW_NOTE ],
	

This is the stuff that makes it slow

You could use the buildbot version of Panda3D.

In order to do so i just need to add the

threading-model Cull/Draw to the config.prc of panda 1.8.0?

I tried that but it seems to be the same

are you, by any chance, loading all notes/taps/whatever in advance so you end up with hundrets of objects to move around?

other than hardcoding the notes, i defined a gameloop

def gameLoop(self,task):
        for i in self.cHandler.getEntries():
            pickedObj = i.getIntoNodePath()
            normalObj = pickedObj.findNetTag('instrument')
            if normalObj.getTag('instrument')==BLUE_NOTE:
                if self.keys['e']:
                    #self.notes[BLUE_NOTE].remove(normalObj)
                    #normalObj.detachNode()
                    #normalObj.removeNode()
                    self.deleteNode(normalObj)
                else:
                    Sequence(
                        self.fadeIn(self.blueerror,0.02),
                        self.fadeOut(self.blueerror,0.02)
                    ).start()
            if normalObj.getTag('instrument')==RED_NOTE:
                if self.keys['r']:
                    #self.notes[RED_NOTE].remove(normalObj)
                    #normalObj.detachNode()
                    #normalObj.removeNode()
                    self.deleteNode(normalObj)
                else:
                    Sequence(
                        self.fadeIn(self.rederror,0.02),
                        self.fadeOut(self.rederror,0.02)
                    ).start()
            if normalObj.getTag('instrument')==GREEN_NOTE:
                if self.keys['i']:
                    #self.notes[GREEN_NOTE].remove(normalObj)
                    #normalObj.detachNode()
                    #normalObj.removeNode()
                    self.deleteNode(normalObj)
                else:
                    Sequence(
                        self.fadeIn(self.greenerror,0.02),
                        self.fadeOut(self.greenerror,0.02)
                    ).start()
            if normalObj.getTag('instrument')==YELLOW_NOTE:
                if self.keys['o']:
                    #self.notes[YELLOW_NOTE].remove(normalObj)
                    #normalObj.detachNode()
                    #normalObj.removeNode()
                    self.deleteNode(normalObj)
                else:
                    Sequence(
                        self.fadeIn(self.yellowerror,0.02),
                        self.fadeOut(self.yellowerror,0.02)
                    ).start()
        return Task.cont

Am i doing this wrong? :X

in guitar hero, only the nodes that are to be played in the next few seconds are loaded and displayed.
i don’t know how you set it up but you should do the same to keep the number of nodes down.

using collision detection seems a bit overhead here,too.
there, probably are faster options.

in any case, you should run pstats and see where your application spends most of its time. this way you can find out what exactly is slow in your code and fix it.

only loading in the few seconds they are played…what I’m trying now is to use less complex 3d objects and hide/destroy the notes after they cross the square

Have you looked at it in PStats to see where it is spending its time now?

Depending on what the bottleneck is, running on multiple cores may not help you at all. For instance, if the bottleneck is too many Geoms, or too much time in the GUI task, or any of a number of other problems, then adding more cores won’t help a bit.

David

I tried but I honestly don’t know how to read it…this is how it looks when the app is running, not sure if a .txt file is also created

can any conclusion be drawn from there?

thank you all!

Basically the taller the graph is, the more time is being spent to render each frame, with the most current frame being shown on the right side of the graph.

Looks like your Python code (App, in blue) is doing more and more work as the program runs. If you double-click on the App heading you may get more detail on specifically what part of your code.

For example, maybe you are creating tasks each frame that keep repeating the same action more and more times.

The Draw and Cull is pretty consistent so I think we can probably rule out too many objects or any rendering issues.

Also, if you are printing out messages (with the print command) it will have a very bad performance hit.

Thank you!

So, i tried looking at the App…the spikes occur when i press the 4 game keys simultaneously (or in really close intervals of time), other than that, it looks like this

What do you guys think? Should I ask someone to help me out and try to put threads in my code?[/img]

Since the rendering is not taking much time, splitting it into threads would not give you a big benefit. It would be much better to find out the real cause of why the program is running slowly.
You can double click the Show code heading and see if there is any more specific information there, usually tasks will show up.
If you have identified the spikes happen when pressing the keys you should look in your code and see specifically what is happening there. You can also add your own headings in PStats to find exactly where the slowdown is, see the “HOW TO DEFINE YOUR OWN COLLECTORS” section in the PStats page of the manual, specifically the sample code for measuring the time taken for a certain function.
The idea is to identify which function is causing the spikes, allowing you to know where to look for the problem.

Thank you for the suggestion…I was trying to figure out the keys but actually, it’s happening even if i just allow the application to run for some time…as i add notes, it gets slower and slower…I’m guessing my code has some problem, I just have no idea what and I’m just using really small plane textures as objects so at this point I really don’t think it’s a performance issue…

if anyone is willing to take a look:
jupiter.esec.pt/~apgomes/madeira/madeira.rar

Edit: seems to be smoother now…i’ll run some more tests and i’ll let you guys know…I wrote some functions for loading the notes and it seems to not overload the cpu

Thank you guys

sneaky little error.

you missed to remove the nodes that don’t get hit in the else-part:

 if normalObj.getTag('instrument')==GREEN_NOTE:
                if self.keys['i']:
                    self.deleteNode(normalObj)
                else:
                    Sequence(
                        self.fadeIn(self.greenerror,0.02),
                        self.fadeOut(self.greenerror,0.02),
                    ).start()

in the ‘else’ part you did not add the removal of the note (as it would pass through) but at the end of their interval they all gather in one spot colliding wildly.

to fix it. add

,Wait(2), Func(self.deleteNode,normalObj)

to your Sequence in the else block for each instrument.
you need to import

from direct.interval.FunctionInterval import Func,Wait

that will wait 2 seconds after the note passes the bottom line, then destroy the note.

Thank you so much Thomas! I will try that as well…we have user testing today so it’s kind of crazy here but later I’ll also post my changes, for reference and for whoever wants to be able to take a look!

Again, thank you

if you want to i can send you a copy of the code with the fix applied. it runs pretty smooth at a constant 85 frames per second on my laptop.