Why main thread is faster than a pthread?

In our OpenGL ES game we have a loading screen (static image) drawn from the main thread at 60 fps and a background loading thread (a pthread actually created with default settings, no priority attributes applied).


Tests show that loading PNG images (involves CPU-heavy zip decompression) from the main thread is 3-times faster than loading them in backgroud thread.

To exclude IO operations and synchronization I have written a simple test. Code like this:

static volatile double outputSlot = 0.0; // volatile to avoid optimizations.
for (int i = 0; i < 1000000; ++i)
   outputSlot = sin(i);


And this code executes 2-times faster on the main thread than on a background thread. Instruments do not reveal any anomalies.

Is it true that the main thread has a real-time priority and is more privileged?

Replies

If you really want to see what’s going on you should look at the System Trace template in Instruments. It will show you which threads are on the CPU and why.

Is it true that the main thread has a real-time priority and is more privileged?

Real-time priority (

THREAD_TIME_CONSTRAINT_POLICY
) exists but does not come into play here. The droid you’re looking for is quality of service, or QoS. The concept was first introduced at WWDC 2014 and has featured heavily in WWDC performance talks since then, so many that it’s hard for me to provide all the links. It’s probably best to start at the beginning, with WWDC 2014 Session 710 710 Writing Energy Efficient Code, Part 1.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

QoS did not helped me but I did a lot of experimenting and the question is still actual.


I have created new OpenGL ES XCode project from scratch. Then I implemented a CPU heavy method which computes sqrt() for real numbers in a loop.

First I measure its execution from the Main Thread before any OpenGL drawing begins. Then the standard logic of the default OpenGL ES application starts with two rotating 3D cubes. I do create a background NSThread and execute the same heavy method from background.


Results are strange. It takes 2x time longer for background thread to complete the task when Instruments say that CPU usage for this background task is 100%. Please see this image: https://monosnap.com/file/5fTphHG52cmT1cTSJBFuSL4F8dLCP7


If I disable any OpenGL ES drawing then background task takes expected amount of time: https://monosnap.com/file/uYanRMNXujUCnWpJGUg9WanoKCNZY1


So how is this possible that task becomes 2x longer while still utilizing CPU for 100% ??? And why this strange behaviour relates to simple OpenGL ES drawing?


And this is iPad Air behaviour with A7 CPU (tested on two identical devices with iOS 9.x and 10x).