Larry OBrien

I wrote some Mandelbrot code that I can divvy up into multiple threads. On my multiprocessor dev box, I get the expected speedups. Identical code on the XBox 360 shows no difference in calculation speed. Does the XNA Framework actually distribute the processing, or is it serially multitasking on a single core




Re: XNA Framework Threaded code shows no speedup on XBox 360: More to it than Threading namespace?

Paul Bleisch

Did you assign the threads to specific hardware threads using the Xbox 360 thread affinity APIs I suspect all of your threads are ending up on the default hardware thread.

Paul






Re: XNA Framework Threaded code shows no speedup on XBox 360: More to it than Threading namespace?

nop

The first thing you call in your new thread has to be Thread.SetProcessorAffinity, otherwise the new thread will be scheduled on the same hardware thread as the thread that spawned it. Check out the XNA documentation for more info.



Re: XNA Framework Threaded code shows no speedup on XBox 360: More to it than Threading namespace?

Walther Gropius

I'm actually seeing something very similar.

I'm procedurally generating a world using a couple of static classes, each of which has a bunch of static methods containing their own fields and so on.

If I call these routines from the main thread (for all 400-odd objects I'm generating) it takes about 22secs. If I split this over 2 threads, each doing half the work, one will take slightly less that 22secs, the other slightly more.

Both threads are updating (different) objects in the same List<>. I thought this might be a problem, so I split the list into two separate lists. Each static method receives an ID param to tell it which list to be looking at. Weirdly enough - this takes even longer!

What am I missing Do things work differently with static methods Help!

Cheers...






Re: XNA Framework Threaded code shows no speedup on XBox 360: More to it than Threading namespace?

Walther Gropius

Oh, and I'm using

Thread.CurrentThread.SetProcessorAffinity(n);

at the beginning of my worker threads.

(Another question - is it safe to hard-code this to ie 3 for one thread, 5 for the other Will threads 0 and 2 always be reserved Are there any guidelines on this )






Re: XNA Framework Threaded code shows no speedup on XBox 360: More to it than Threading namespace?

ryan.rogers

I'm interested in this as well, just last night I started working on updating my inflater / deflater to work across several background threads so that decompressing files will be as fast as possible (System.IO.Compression is not in 360CF if you did not notice. ;-).

The main guidelines that I have extrapolated from reading the docs are:

- don't use the reserved hardware threads 0 and 2 (duh ;-)

- all hardware threads are not created equal. In partiuar:

a) 4 and 5 share L1 cache

b) None of the available background hardware threads will EVER share L1 cache with your main game thread running on hardware thread 1.

From this I can further extrapolate the following, but please note that I have not actually tested this as of yet but they should hold true:

* if you have three or more background threads and two of these do a lot of sharing of a small dataset, you will probably realize a shared cache benefit by running them on 4/5. You should test to confirm though while tuning.

* conversely, if you have two threads that are totally independent wrt the data they touch, it would be a good idea to make sure they do NOT go on 4/5, as they will fight each other for L1 cache. You should test to conifrm though while tuning.

* a logical model whereby all background threads are "slaves" to the main game thread may not be always be best, as not all background hardware thread ID's are created equal. A tiered model whereby the main game thread itself leverages a multithreaded component may make more sense in certain conditions, and that component can leverage locality of encapsulated data and therefore make a good candiate for targetting 4/5.

In short, 4 and 5 are special in that they are the only two of the four available (to us) hardware threads that run on the same physical core, and therefore therefore share the same L1 cache. This can work for you, or against you, depending on the locality of the data the threads are touching. Furthermore, none of the available background hardware thread ID's will ever share L1 cache with your main game thread, but they can with each other, which is an important principle to keep in mind when designing your threads. Therefore, the mantra, all hardware threads are not created equal.

As such, I think it is important when designing your threading model that you take both of these into account and use them to your advantage (or at least not to your disadvantage). This is one of those cases where you definately should to keep the metal in mind up front during design. Overhauling the thread model (restructuring your code to add / remove background threads) is not something you want to be doing in the tuning phase as it may necessitate significant code refactoring.

Ryan





Re: XNA Framework Threaded code shows no speedup on XBox 360: More to it than Threading namespace?

nop

It's safe to hardcode the values. XBOX = console = fixed hardware configuration, so this won't change on you.

As for your threading code there are a few things you could be doing that would make it behave as you describe:

  • Are you creating the thread each frame Don't do that since it's expensive. Just create a thread for each CPU you want to use at the start of your game and leave them up all the time. Have them wait on some synchronization object until you've got work for them.
  • Do you have a lot of synchronization code in your threads Ideally, you should have your main thread set up a batch of work, and kick that batch off on the other thread. The data it uses should be considered totally off-limits by all threads but the worker thread which allows it to just do it's work without locking various objects all the time. Remember too, if an object is only being read, you don't have to protect access to it with a lock (just make sure you don't write to it untill all other threads are done with it).
  • Are you allocating a lot of objects I'm not positive on this but I'm pretty sure the garbage collector will pause all threads when it has to run a collection. That might be a hidden source of synchronization between the threads.




Re: XNA Framework Threaded code shows no speedup on XBox 360: More to it than Threading namespace?

Larry OBrien

Update: Using SetProcessorAffinity() at the beginning of my ThreadStart delegate worked perfectly.