Slow down...

Started by
6 comments, last by fmatak 15 years, 9 months ago
Hi All, I am trying to code an engine (as everybody else here) and I have a problem. My engine is supposed to be threaded. One thread is for display & graphics etc. usual tasks and the other thread is (there are exactly 2 threads) for the scripting VM. I have a dual core processor, so supposedly, both threads should be running on their own processor. That is why I am expecting the scripting thread should not drop FPS. When I disable scripting and just go with single thread, I got FPS about 40. When I enable scripting, and go with 2 threads, I get 15 to 20. There are 2 places which might be responsible from this, I think. One is the thread affinity setting used in QueryPerformanceCounter function, (to prevent bugs in dual core systems.. mentioned in some other thread in gamedev) And the other one is the WinAPI mutex thing I am using. (Scripting system can send data to display on screen, so there is some amount of shared data. And I am using it to prevent concurrent access to the data.) So, I commented out the timer call from the scripting thread, so it will not change the thread affinity. But this did not seemed to help. So, I assume the problem is with mutex.. (other ideas are also welcome) So, I decided to write my own mutex. Since I am only trying to sync 2 threads, no interprocess things etc, a very lightweight thing would be enough.. But before beginning on that, I wanted to ask you, which libraries do you use for that and is there any lightweight libraries you can recommend? (I do not use boost, and I am not planning to use it for this project only for mutex) (I also do not use/do not plan to use pthreads or any other threading libraries.) By the way, I am coding in C++. (using OpenGL) Any help/idea/references appreciated..
Advertisement
It is impossible to tell without actually seeing your code, but I'd put my money on the problem lying in the design of your thread interaction, rather than the functions you are using to coordinate said interaction. How frequently [say, # of times per frame] and for how long are you locking for shared data, and does this locking result in a mandatory stall in either thread. Ideally, the shared data passed around in this sort of configuration would occur in a single point between frames, where the rendering thread receives a buffer of updates from the scripting thread and applies them to the next iteration. Please elaborate on the manner in which you coordinate thread interaction?

In all honesty though, thread affinity isn't likely an issue, and you would likely be seeing the exact same problem with a single processor machine [or a quad processor, or whatever] if the problem is what I am expecting it is. Two threads likely isn't enough to max out even a single processor. Especially when one of those threads has an I/O component to it [rendering].
Do both threads have write-acces to the shared resource section?
I would imagine at some point you are locking something that probably shouldn't be locked, and so one thread is waiting for the other far too frequently. I doubt the problem is with the OS mutex, but probably your use of it.

Take a few minutes to re-evaluate your design and see if you can find any bottlenecks.
Let me explain a bit more details..

There is a text render queue. Script system appends text info to the render queue. Each item in queue has a life time, screen coordinate etc. When it times out, it is removed from the queue. Each frame, the rendering thread, goes over the queue and renders the texts. And if the text's life time is over, it removes it from the queue. So, render thread actually accesses and locks the mutex once per frame. But the scripting thread possibly accesses it multiple times.

For testing, I added some Sleep calls to the scripting thread (which was smt like 100 ms execute 100 ms sleep), which eventually caused frame rate to increase. (This is also one of the reasons why I am suspecting the mutex thing)

I think, the mutex thing takes some longer time than the actual operation inside it, so it causes both threads loose time waiting the other thread release the mutex. (Unfortunately I did not made a string timing for that yet)

To sum up... I think you are right about my design. It seems to be problematic, but I could not come up with something better. Whatever I do, I will need to lock the queue. (apparently, the locked things will eventually increase when I add new things..)

Maybe I should change the rendering thread to a read only one, and update it only from a single thread. I do not know. If you have any idea please share with me. Thank you.
Every time you lock this queue with your render thread, you can't access it with your script thread, and the same the other way around. If you hold the lock within the render thread until the rendering is done, then you end up with a situation in which you have a sequentially running render part, and a sequential script part, and no multitasking.

Here is something to try. Have two of these queues. One sitting inside the render thread, and one inside the scripting thread. The scripting thread only writes to its own queue, and locks it each time it does so. The scripting thread never touches the render thread's queue. Once each frame, the render thread locks the scripting thread's queue, and dumps everything in it into it's own queue, and then unlocks it [doesn't actually process any of the data, just pops from one and pushes into the other]. The render thread then churns over the data in its own queue, and the scripting thread proceeds to fill it's own queue up again.
@ Drigovas

Actually I thought the double queue thing before, but then I thought it would be slow to copy everything each time. But what you say makes sense. It could actually be waiting until the text is rendered. I will try this and see what happens. Thanks for the clue.
I did it and it seems to be working great. Thanks for your help.

This topic is closed to new replies.

Advertisement