Fun with concurrency on a single core
I have a single-core chip on iPhone 4 and an app with OpenGL rendering controlled by touch events.
This morning the app was rendering graphics on the main thread. 90% of CPU time was spent on graphics, 10% on gesture recognition and related computations. Overall CPU utilization was about 30%.
These 30% were noticeable: touch events were processed with delays and frame rate was low and not very stable.
In order to make app snappier, I moved the OpenGL rendering into separate serial dispatch queue. Now event loop was much less loaded, and I expected overall improvement. Not a higher framerate, but more stable one and with more accurate touch recognition.
In reality, the rendering was indeed slightly smoother, but touches were still delayed.
Profiler was showing now that 70% of CPU time was spent on graphics (in background thread) and 30% was spent on gesture recognition. Also, overall CPU usage increased up to 50%.
In terms of raw performance of algorithms nothing was changed at all. Threading code that was added is a simple dispatch_async() call consuming almost no time.
Now, I have a theory that explains this. Since the main event loop became 90% less loaded after moving graphics to background thread, it was able to process more touch events per second. Gesture recognition computations increased load on a single CPU core making graphics rendering slower than expected.
In result, framerate was not improved, but became more stable and touches didn’t get much smoother because of the increased pressure on CPU and main thread.
It turns out that rearranging stuff on a single core does not really help unless it is accompanied by actual performance improvements.
