I want to parallelize some code so it runs faster on multiple processors, like this (pseudocode in C++):
semaphore sem;
thread_safe_type result;
int main(char **args)
{
sem = new sem();
job();
printf("result: %d", result);
delete sem;
return 0;
}
int job()
{
for (int i = 0; i < 10; i++)
run_thread(task());
p(sem);
return result;
}
void task()
{
result.dostuff(); // do some stuff to "result"
v(sem);
}
Essentially I have some code that needs to be run on all entities within the 30ms frame. I thought I could speed up execution if I ran them in parallel. Coroutines can do something like that, but there is no “semaphore”, and I can’t do a “yield return” outside of a coroutine.
Hmm… what to do?
AFAIK, coroutines don’t run in parallel. The dispatcher runs one until it finishes or yields, another … . So you never have to worry about race conditions like two guys saying: n=cows; n++; cows=n;
. But, breaking into coroutines “just because” won’t gain any speed.
You can safely use bools and ints as informal semaphores and mutex variables. A Wait can safely be done with while(soundPlaying) yield; soundPlaying=true; ... soundPlaying=false;
(which would have a race condition in parallel.)
The main advantage of coroutines is ease of reading (like “over the next 20 frames, decrease alpha”.) And when you want to wait 2 seconds, yield 2.0 (really sleep) runs faster than if(Time.time>doStuffTime)
each frame (but mostly for readability, there too.)
To add to Owen’s answer - you can use .NET threads and thread locking operations in Unity - you need to import the System.Threading namespace. Be aware that only the main thread can access any Unity objects - other threads can do calculations and use other .NET methods (like talking to servers etc). The simplest method of locking in .NET is to use the C# lock keyword which provides a critical section:
public MyClass something;
lock(something)
{
//Critical section code goes here
}