- Home /
Efficiency of coroutine and what it does?
So I found another answer http://answers.unity3d.com/questions/255647/Yield-vs-update.html
Which explained a bunch, but I'm about to pry even deeper. I watched the Intermediate Video on using Co-Routines and in the comments, he said "It's much faster to use Yield than to re-initialize everything", unfortunately that is everything I know about that.
So when I see a yield in a return statement (I come from C++), first, I have to get used to it (I realize there are ways to code that are better in Unity3D I should accept, so I won't argue that). However, I want to know what this does.
In Fork(), I only know a bit, but it seems that "The process is copied, including any active registers/ram use" (quotes mean paraphrase here btw). I'm not a comp sci major, so this is what I've skimmed on other answer sites and a book on OS's that I read up to threads.
So does yield copy the process? Does it need the sigaction to handle its zombies, which is why the other answer (link above) mentions gc? Also I only know about sigaction from Beej's guide to network programming . I'm not an expert.
However, I am aware the OS has "signals" it sends and you can respond to them, probably not a Unity3D thing though.
Finally, and this might be out of scope for Unity3D forums, is what does Fork() do exactly? So if I yield, and it's the same thing with a coroutine, does it really copy the whole process over? I realize the bulk of the program is the media, but I used to think of programs as one thing, that loops or goes wherever, but this threading thing makes me think it's just a series of "runnable functions", that sleep, wake up, split/fork and come back whenever, and I'm having a harder time grasping what a program is vs a process, and how this relates to whether it's more efficient to use a coroutine or just reinitialize the variables.
And that, was how I brought this back to Unity3D discussion. However, feel free to say "For the other half, head to Stack-O and ask that there"
It seems I may be way off, they are just state machines that move the code into the start function? http://www.cpudreams.com/2010/02/coroutines.html thanks to a similar question... I may delete this question if it's not found helpful. Thanks.
for me it is helpfull only to find that link and than I saw that invoke does not make garbage collection.
but I can't say anything about memory and stuff I'm not that hard in it yet.
Answer by Dave-Carlile · Nov 02, 2013 at 04:59 AM
Here's a good Unite 2013 talk on co-routines.
https://www.youtube.com/watch?v=ciDD6Wl-Evk
Internally they're basically a list of class instances (one per executing co-routine) stored in a collection. Each instance is a state machine, and uses the IEnumerator interface to iterate through the states using MoveNext
.
Answer by aldonaletto · Nov 02, 2013 at 04:49 AM
I don't know about Fork(), but in Unity a coroutine implements a kind of background processing. Once started, a coroutine executes independently of the caller code, which's free to go ahead and do other jobs - it's like a parallel machine running the coroutine "at the same time". Actually, the whole thing is done by software: when you start a coroutine, an instance of it is created and runs until a yield instruction is found, when control is returned to the caller code. In the next frame (after all Updates), Unity awakes the coroutine automatically, which continues executing until another (or the same) yield freezes it again till the next frame, and so on. It's a cooperative system: if a coroutine enters an infinite loop due to a missing yield, Unity freezes and you must close it (and loose your work...). I don't know exactly how they do it, but each coroutine instance has its own stack, what allows temporary variables to keep their values independently of their equivalents in other instances.
Coroutines are efficient, but allocate memory: avoid starting coroutines very often (each frame, for instance), because this will cause more frequent garbage collections and reduce performance.
Yeah - it's basically just a class instance stored in a collection. Unity loops through the collection each frame and executes the IEnumerator's $$anonymous$$oveNext function.
Thanks for the explanation, and even though it's very detailed, and contains the extra instance I didn't know about (which I'd vote up if I had 15 rep by now, can I transfer some SO rep, hehe), I was prying into the garbage collection/process stuff. I think I need to ask or find that on SO, I'm quite puzzled as to how you can "interrupt the main thread" and not interfere with it, and I'm not a new coder, but very new to the insides of this stuff.
Thanks again! I do appreciate your answers!
It's not actually interrupting the main thread. It's just a list of objects. At some point in the main game loop - I believe at the end of each frame - Unity goes through the list and deter$$anonymous$$es which CoRoutine is ready to run. For each one that's ready, Unity just calls $$anonymous$$oveNext
. That's a simplified explanation, but basically the way it happens. There's really nothing magic about it - just loop through a list of objects checking their state, and moving them to the next state.
Yes, there's no real parallel processing or multitasking. Unity basically runs an endless loop while running (simplified sequence):
1- call Update in all scripts;
2- goes through the coroutine list, resu$$anonymous$$g the execution of each coroutine until a yield freezes it and passes to the next one in the list;
3- call LateUpdate in all scripts;
4- render all cameras in the screen and return to step 1;