- Home /
Extreme amounts of processing crash android build?
I am doing way too much work on my built out APK, to the point where it loops through 16 million or more items (which is 4 color32 arrays each of the pixels from 4 2048x2048 textures) and it must assign the alpha value of those 16 million colors, to one huge 16 million sized integer array. I am doing this to avoid calling GetPixel a ton while doing some work further down the line, so it doesn't beat up performance when it is out of the loading phase.
So yeah I thought, hey I'll make this a coroutine, and just like, call yield return new WaitForSeconds(0.0000001f) - and that way, it should briefly pause between each of the 16 freakin million values, but not so much it really causes a slowdown, but just enough to prevent the android processor/memory from getting overloaded. So thats 0.0000001f (six zeros) times 16 million = roughly 1.6 seconds of real time... right?
No that is not right. When it reaches this part (in editor or on device) it slows to a freakish crawl. Like 2 minutes or something to get through this section? Is my math wrong? Is floating point accuracy screwing with me? What is going on here?
I tried moving the yield to only get called after each X row, and before it iterates up the Y values, it yields the 0.0000001f... but then it should only be called 4096 times. Butttt... still takes about a minute or so to load (although I should point out it doesn't crash the android build this way, just takes forever to load the world...)
Here is that code - remember, World Width and World Height are both 4096:
for(int wY = 0; wY < WorldHeight; wY++) // iterate through y pixels
{
for(int wX = 0; wX < WorldWidth; wX++) // and x pixels
{
int worldIndex = GetWorldPixelIndex(wX, wY); // of every pixel in the world, get this ones pixel index
worldAlphaPixels[worldIndex] = Mathf.RoundToInt(GetSourcePixelNonLocal(GetCellIndex(wX, wY), wX, wY).a); // set color to matching source pixel
}
yield return new WaitForSeconds(0.0000001f); // take a processing break, stuffs about to get intense
}
Your waitforseconds will never work as expected. Update or FixedUpdate from frame to frame can not measure time that accurately. Try leaving it out. Its adding more time than you think.
Answer by Bunny83 · Nov 19, 2014 at 09:54 PM
WaitForSeconds will wait at least 1 frame. Coroutines are processed at a specific point in the main loop. No matter how small you choose your "delay" you will at least wait Time.deltaTime ;) Keep in mind it's a single thread environment.
In such cases when it comes to loading at the beginning it's always difficult to find a balance between yielding and just doing the work. The OS will simply assume your app is crashed when it doesn't respond for a certain time span. In such cases it's uaually the easiest to simply yield after a certain amount of time has passed. Of course you can't use Time.time since it only updates per frame. Time.realtimeSinceStartup should work for this or use System.DateTime.Now. It should be combined with a counter so you don't check the time every iteration.
public class WatchDog
{
private int m_Counter = 0;
private int m_MaxCounter = 1;
private float m_LastUpdate = 0;
private float m_MaxTimeStep = 0.4f;
public WatchDog(float aMaxTimeStep, int aMaxCounter)
{
m_MaxTimeStep = aMaxTimeStep;
m_MaxCounter = aMaxCounter;
}
public bool NeedABreak()
{
if (++m_Counter > m_MaxCounter)
{
m_Counter = 0;
if (Time.realtimeSinceStartup-m_LastUpdate > m_MaxTimeStep)
{
m_LastUpdate = Time.realtimeSinceStartup;
return true;
}
}
return false;
}
}
With that class you can check this quite easy:
WatchDog wd = new WatchDog(0.3f,10);
{
// inside your coroutine loop
if (wd.NeedABreak())
yield return null;
}
This would check every 10th iteration if the the passed time has exceeded out max time of 0.3s. If that's the case the function will return true and you would do a yield return null to wait a frame.
That way you get most out of the CPU without making the OS angry. You might have to adjust the max time. Note: The max counter shouldn't be too high .
Bunny this sounds like a good answer, I'd try it out, but my gf spilled mountain dew in my notebook I work from. Thankfully the project is backed up, but it will take me a day or two getting all my stuff set up on my other computer before I can test it out. Just my luck :) I'll probably be back to mark you correct whenever I get that all sorted out, thanks for going into such detail for me!
Get inside with a toothbrush and warm soapy water before the metal corrodes :D it can be saved!
(Dip the brush, soak off excess, gently rub on sticky patches)
If its warm enough it'll evaporate as you go.
I appreciate your advice @meat5000 , but problem is I didn't get to it in time - I was out at work, and she had tried to get the fluid out... by turning it upside down to pour it out of the keyboard - while it was plugged in to power adapter... with the battery in... turned on...
I assume there was a sizzling smell and sound followed by my LCD turning white, and forever thereafter not rendering...anything, Dew must have somehow got to the integrated radeon video card out of the little protective bay below the keyboard when it was tilted :/
So yeah, I am ordering a similar model with a cracked screen and working motherboard online to get it swapped out and back up and running. Until then I am stuck on a little tiny (11 inch?) sub-notebook - which ironically - is only fueling the fire that is my slow loading times while using the editor! Haha. No seriously development has come to a crawl quiet literally. Just downloading Unity and setting up for android development has been time intensive on this slow sucker of a machine.
I haven't had a chance to try your answer out yet @bunny83 - hopefully sometime later this afternoon I can try that out and see - without even building out to device - if it makes the difference in loading times!
Your answer
Follow this Question
Related Questions
yield return request never returns 2 Answers
Coroutines (likely) running far too slow on Android, what's the issue? 2 Answers
Yielding with WWW in Editor 9 Answers
WaitForSeconds(3) on Android waits less than expected 2 Answers
coroutine or yeild for OnGUI? 0 Answers