Page 1 of 1
Question about Thread Workers
Posted: Wed May 18, 2011 5:18 pm
by Arcades
Hello,
I'm start using BEPU for our project and, as in the subject, I have question about it's multi-threading system.
We are developing a game for Xbox 360 for the live marketplace so we are using XNA.
Since we are limited to the XNA framework we have a main thread for the application (which is also the rendering thread) and the remaining 3 for everything else (for the updating phase). Actually our implementation split the updating phase in the remaining 3 threads. Now, after their work the threads are free and we are going to use them for BEPU. Now the problem is we use a threadpool for avoiding the creation and destruction of the threads which is expensive, what we do is just put them to sleep and change the function they call when they are awake. As far as I've seen BEPU create and destroy threads when the client use AddThread() and RemoveThrea() in the manager classes.
We wish to pass them our threads, use our own thread management (which also could lead use to dynamical give or remove thread to BEPU each frame, in case of need (of course not when BEPU is working, during it's update phase)). Is there a way to achieve this in a clean way?
Thank you for your replies.
Re: Question about Thread Workers
Posted: Wed May 18, 2011 7:06 pm
by Norbo
You could create an IThreadManager implementation that uses your own thread manager behind the scenes and then give that to the Space.
The default ThreadManager does create/destroy threads when they are added/removed, but that is typically only done at initialization. There may be a very tiny bit of overhead for keeping a few more threads blocked until they are needed, but it shouldn't be a huge problem.
Also, watch out for load balancing issues, especially if a core's two hardware threads are working at the same time. If your thread manager does dynamic load balancing on the Xbox, it may turn out okay, but I found that it's usually best to hold its hand at every step. More information on the system can be found here:
http://bepuphysics.codeplex.com/wikipag ... umentation
Re: Question about Thread Workers
Posted: Thu May 19, 2011 12:30 pm
by Arcades
I was missing I could set the ThreadManager.
Thank you for your reply.
Re: Question about Thread Workers
Posted: Tue May 24, 2011 4:56 pm
by Arcades
Hi again,
I have one more question about this matter.
I developed my own ThreadManager and it works, alone and with BEPU. But as far as I've seen the Space class constructor make a new ThreadManager and set it to it's every subsystem.
Then if I set my own ThreadManager class to Space, this simply ignore my class.
Did I miss something?
For testing purpose I modified the Space class with adding a constructor which get in input a ThreadManager however I wish to avoid to edit things in the BEPU source code.
Regards.
Re: Question about Thread Workers
Posted: Tue May 24, 2011 10:10 pm
by Norbo
In the development version (
http://bepuphysics.codeplex.com/SourceC ... evelopment), the Space.ThreadManager set assigns all stage thread managers as well.
Re: Question about Thread Workers
Posted: Wed May 25, 2011 12:57 pm
by Arcades
Thanks again for your reply.
I'll work on it.
Re: Question about Thread Workers
Posted: Tue Jun 07, 2011 1:23 pm
by Arcades
Hi again.
I was managed to write a working ThreadManager which use my worker and my thread. The manager works well and I'm able to load balance the works between thread as I wished to.
I still have some problems:
In the ForLoop method I was using another algorithm for split the tasks but it seems BEPU is a bit susceptible about how I subdivide them. I'm testing the ThreadManager with the demos provided with the engine. In the first demo (WallDemo) the ForLoop receive quite often a task of 107 iteration. Now (with four threads) the internal manager divide the tasks in four subdivision with this iteration range: 0-23, 23-57, 57-83 and the last 83-107. (it mean the first task loops from index 0 to index 22, the second from 23 to 56 and so on)
My algorithm subdivided the tasks this way: 0-24, 24-58, 58-84, 84-107. BEPU crashed. When I switched to the (almost) same algorithm of BEPU it doesn't crash anymore. The crash is related to a null reference in the DynamicHierarchy class.
Now I wonder why: as far as I've seen from the debug I have no error on my workers, this make me think BEPU do some assumptions on the ForLoop like it need some range to be sequential, like every quarter of the loop must be done sequentially, that's could explain the first subdivision (0-24) crash (instead of 0-23).
Ok, I use an algorithm which produce the same index as the internal BEPU's thread manager and the for loop doesn't crash anymore. This is ok for me but I wish to know why.
The other problem is bigger:
As I've wrote before I need to load balance the thread this mean every frame I have to load balance the threads. This mean I can give to BEPU sometimes one single thread, sometimes four, three or any.
I have a crash after 2 seconds on the demo if I work this way.
Now I don't wish to go into the details because this would take much time. For now I wish to know: does BEPU make assumption on how many thread it have before working with them? Anyhow?
Thank you for the info.
Re: Question about Thread Workers
Posted: Tue Jun 07, 2011 2:48 pm
by Norbo
My algorithm subdivided the tasks this way: 0-24, 24-58, 58-84, 84-107. BEPU crashed. When I switched to the (almost) same algorithm of BEPU it doesn't crash anymore. The crash is related to a null reference in the DynamicHierarchy class.
I don't know of any reason why this should occur. Was this using v0.15.2? Was it on the PC or Xbox360 (Xbox360 should focus on only 3 cores though)? You may want to try the latest development versions that include the rewritten DynamicHierarchy. However, threading problems are notoriously difficult to pin down, so it's unlikely I'll be able to guess the correct answer without a repro case.
BEPU do some assumptions on the ForLoop like it need some range to be sequential, like every quarter of the loop must be done sequentially, that's could explain the first subdivision (0-24) crash (instead of 0-23).
There are no requirements on the execution order- it is assumed they could execute in any way. The default PC ForLoop includes a form of workstealing, so it already has no guarantees of order.
For now I wish to know: does BEPU make assumption on how many thread it have before working with them? Anyhow?
Changing the thread count while something is executing will probably mess something up. If all the threads are idle, it shouldn't matter unless there's a bug. BEPUphysics does rely on the thread count reported by the thread manager, though. An incorrect thread count may cause threading to be unused, but unless it was negative or something, I can't yet guess how it would cause a crash.
Re: Question about Thread Workers
Posted: Tue Jun 07, 2011 3:05 pm
by Arcades
Thank you again for your reply.
My tests were all done on PC a dual-core, I forced both my ThreadManager and BEPU's internal ThreadManger to use 4 threads. BEPU version is 0.15.2 from source (I compiled against x86 debug).
Well those informations are enough, I'll recheck everything again.
Re: Question about Thread Workers
Posted: Thu Jun 09, 2011 2:33 pm
by Arcades
Hi again.
I finally managed to solve everything. I finally have a working ThreadMangager with a dynamic load balancer. I still have a question tough it's not very important but I hope you many answer:
as I've seen from debug the DynamicHierarcy split into 2 threads and do some nasty stuffs with it's node and entries indexes. I didn't delve deep into the code and I'm not sure I have enough brain cells left for do it. The question is: if no thread (hardware, like on xbox) are available does it split anyway? How does it?
I think it will be not an issue but I wish to try to understand before an eventual problem if there is something to care about (like if I have to leave a thread for the DynamicHierarchy or something similar). This because actually I'm not moving to the newer release of BEPU, I'll test them in the future but for now I'm stuck with 0.15.2 (which it's stable, I think).
Thank you very much, Norbo, for you support.
Re: Question about Thread Workers
Posted: Thu Jun 09, 2011 3:31 pm
by Norbo
if no thread (hardware, like on xbox) are available does it split anyway? How does it?
If the ThreadManager has 0 or 1 threads in it, or if the AllowMultithreading property is set to false, it will use the single threaded path which does not do any task creation at all.
Re: Question about Thread Workers
Posted: Thu Jun 09, 2011 3:56 pm
by Arcades
I see.
But if I have more then 1 Thread then this threads are set to the ThreadManager and are used for the ForLoop and/or EnqueueTask functions and then, inside a EnqueueTask the DynamicHierarchy get 2 more threads.
DynamicHierarchy should rely on ForLoop and EnqueueTasks, instead inside a EnqueueTasks it split on 2 more threads. Is this correct?
I was in a testing environments with a thread for the applications, 4 sets to the manager and then 2 for the DynamicHierarchy, too many.
Re: Question about Thread Workers
Posted: Thu Jun 09, 2011 4:13 pm
by Norbo
DynamicHierarchy should rely on ForLoop and EnqueueTasks, instead inside a EnqueueTasks it split on 2 more threads. Is this correct?
Any number of tasks could be enqueued. They should not create additional threads unless the thread manager's implementation deems it useful; each task represents a unit of work that is distributed to one of the waiting threads.
All of the built-in thread managers used a fixed pool of threads since they are known to be continually re-used. The TPL is a slight exception, since it manages its threads internally, but it will very likely converge towards using a fixed set of threads when working on physics every frame. Creating a whole thread for a single task will badly hurt performance.
Re: Question about Thread Workers
Posted: Thu Jun 09, 2011 4:17 pm
by Arcades
Maybe I explained wrong.
My ThreadManger is set and my ThreadManager have 4 threads, DynamicHierarchy do call EnqueueTask but then, inside a task executed by my own Worker class, DynamicHierarchy split into 2 more threads outside my control. This is what I've seen from the debugger and it's no a behaviour I like. Why should it split if it rely on EnqueueTask?
Re: Question about Thread Workers
Posted: Thu Jun 09, 2011 4:24 pm
by Norbo
Nothing in the DynamicHierarchy itself creates additional Threads. It does, however, recursively call EnqueueTask. This is normal usage of the task system.