Search Unity

Is Unity Multithreaded?

Discussion in 'Editor & General Support' started by Julien-Lynge, Nov 30, 2013.

  1. Julien-Lynge

    Julien-Lynge

    Joined:
    Nov 5, 2010
    Posts:
    142
    There was a great discussion a while back about whether Unity itself is multithreaded, and whether you can use multithreaded code with Unity: http://forum.unity3d.com/threads/67879-Is-Unity-multi-threaded. The last posts were from 2011, and things have changed quite a bit then, so I thought I'd start a new thread for discussion.

    I was curious about this myself, so I poked around to find what information I could and then bugged an awesome Unity developer* that gave me a bit more info. Here's what I learned:

    Recent versions of Unity introduced more multithreaded editor improvements like substance reimports (from http://unity3d.com/unity/whats-new/unity-4.2 ), and skinning can be done on the GPU (DX11, Pro only), which technically isn't multithreaded but does run massively parallel outside the CPU, so you know, basically the same thing :)

    Additionally, going forward Unity is looking at the following:

    So hooray for Unity - sounds like some good progress in moving to multithreaded support.

    *whom I won't name, because I don't want to get him in trouble; if I get anything wrong here, I don't want people blaming him :)

    /////////////////////////////////////////////////////////////////////////////

    Additionally, there's the question of whether a developer can use multithreading in their code with Unity. I think dreamora had a pretty nice post explaining this, which I've copied below.

    In a nutshell: you can create and manage your own threads on as many cores as you want. You can also do just about anything C# allows you to on these many cores, as long as you don't try to change anything Unity is actively managing. This includes any transform stuff, game object stuff, component stuff - anything in scene, or a part of Unity's rendering process.


    What this means is that you can go off and do all kinds of math, database management, AI algorithms, etc. However, when you want to take the results and apply them to the scene, you have to transfer all that data back to the main thread and do it from there - you can't access any Unity objects from other threads. As Eric5h5 explains, this really isn't that big of a limitation:
     
    chiranjiv and AntonioModer like this.
  2. Julien-Lynge

    Julien-Lynge

    Joined:
    Nov 5, 2010
    Posts:
    142
    I forgot to mention multi-threading with the webplayer: according to ArenMook (back in 2011), multithreading works in the webplayer but doesn't allow mutexes:

    http://forum.unity3d.com/threads/76087-WebPlayer-Multi-threading

    I haven't played around with this myself, so I can't verify whether this is still the case. Does anyone have any experience with multi-threading on mobile and other platforms?
     
  3. Simon-O

    Simon-O

    Joined:
    Jan 22, 2014
    Posts:
    51
    I'm new to Unity but have a strong .Net background so while I haven't tried this, I don't see why it wouldn't work...

    If the Unity interaction has to be single-threaded, there's no reason background threads can't "phone home" with desired updates and allow the main thread to make them. This is similar to WinForms which requires that all controls be updated from the UI thread.

    Something like (untested):

    Code (csharp):
    1.  
    2.     public AudioClip TestClip;
    3.     public AudioClip TestClip2;
    4.     private System.Object QueueLock = new System.Object();
    5.  
    6.     void Update () {
    7.  
    8.         var WorkQueue = new Queue<System.Action>();
    9.         Thread T1 = new Thread(() => DoWork(WorkQueue));
    10.         Thread T2 = new Thread(() => DoOtherWork(WorkQueue));
    11.         T1.Join();
    12.         T2.Join();
    13.  
    14.         foreach (var Action in WorkQueue) {
    15.             Action.Invoke();
    16.         }
    17.        
    18.     }
    19.  
    20.     void DoWork(Queue<System.Action> Queue) {
    21.         //Do some work
    22.         lock (QueueLock) {
    23.             Queue.Enqueue(() => audio.PlayOneShot(TestClip));
    24.         }
    25.     }
    26.  
    27.     void DoOtherWork(Queue<System.Action> Queue) {
    28.         //Do some other work
    29.         lock (QueueLock) {
    30.             Queue.Enqueue(() => audio.PlayOneShot(TestClip2));
    31.         }
    32.     }
    33.  
    Of course the above example assumes that the main thread will do nothing but wait for all child threads to finish, then run the Unity commands they've queued up. If you know enough to be using threading, you can see how you could skip using Join() and instead have the main thread do work and check on the queue occasionally for things to execute.

    You should also be aware that while things in the queue will be executed in order, there's no guarantee what order they'll be placed into the queue. The good news is that since all we're doing is running anonymous methods, it's possible to queue up a block of code at once...

    Code (csharp):
    1.  
    2.         Queue.Enqueue(() => {
    3.             audio.PlayOneShot(TestClip);
    4.             audio.PlayOneShot(TestClip2);
    5.         });
    6.  
    Now we don't know what order the block will be called in but we do know all commands in the block will be executed in order and no commands will be "mixed in".

    As I said, I'm new to Unity so take this with a pinch of salt - perhaps someone more familiar with Unity could confirm/deny my understanding?

    Note that since Unity seems to be targetting .Net 3.5 you can't use the ConcurrentQueue<T> thread-safe queue, hence needing the lock or a similar mechanism.
     
    Last edited: Jan 26, 2014
    DarkSchneider and Misk-DHI like this.