views:

61

answers:

2

For a normal app, you'd never want to do this.

But ... I'm making an educational app to show people exactly what happens with the different threading models on different iPhone hardware and OS level. OS 4 has radically changed the different models (IME: lots of existing code DOES NOT WORK when run on OS 4).

I'm writing an interactive test app that lets you fire off threads for different models (selector main thread, selector background, nsoperationqueue, etc), and see what happens to the GUI + main app while it happens.

But one of the common use-cases I want to reproduce is: "Thread that does a backgorund download then does a CPU-intensive parse of the results". We see this a lot in real-world apps.

It's not entirely trivial; the manner of "being busy" matters.

So ... how can I simulate this? I'm looking for something that is guaranteed not to be thrown-away by an optimizing compiler (either now, or with a better compiler), and is enough to force a thread to run at max CPU for about 5 seconds.

NB: in my real-world apps, I've noticed there are some strange things that happen when an iPhone thread gets busy - e.g. background threads will starve the main thread EVEN WHEN set at lower priority. Although this is clearly a bug in Apple's thread scheduler, I'd like to make a busy that demonstrates this - and/or an alternate busy that shows what happens when you DON'T trigger that behavioru in the scheduler.

UPDATE:

For instance, the following can have different effects:

for( int i=0; i<1000; i++ )
    for( int k=0; k<1000; k++ )
    CC_MD5( cStr, strlen(cStr), result );

for( int i=0; i<1000000; i++ )
    CC_MD5( cStr, strlen(cStr), result );

...sometimes, at least, the compiler seems to optimize the latter (and I have no idea what the compiler voodoo is for that - some builds it showed no difference, some it did :()

UPDATE 2:

25 threads, on a first gen iPhone, doing a million MD5's each ... and there's almost no perceptible effect on the GUI.

Whereas 5 threads parsing XML using the bundled SAX-based parser will usually grind the GUI to a halt.

It seems that MD5 hashing doesn't trigger the problems in the iPhone's buggy thread-scheduler :(. I'm going to investigate mem allocations instead, see if that has a different effect.

+1  A: 

You can avoid the compiler optimising things away by making sure the compiler can't easily infer what you're trying to do at compile time.

For example, this:

for( int i=0; i<1000000; i++ )
    CC_MD5( cStr, strlen(cStr), result );

has an invariant input, so the compiler could realise that it's going to get the same result everytime. Or that the result isn't getting used so it doesn't need to calculate it. You could avoid both these problems like so:

for( int i=0; i<1000000; i++ )
{
    CC_MD5( cStr, strlen(cStr), result );
    sprintf(cStr, "%02x%02x", result[0], result[1]);
}

If you're seeing the problem with SAX, then I'd start with getting the threads in your simulation app doing SAX and check you do see the same problems outside of your main app.

If the problem is not related to pure processor power or memory allocations, other areas you could look at would be disk I/O (depending where your xml input is coming from), mutexes or calling selectors/delegates.

Good luck, and do report back how you get on!

JosephH
Yep, that's good idea, thanks. I'll try shunting flipping them on alternating cycles, and nslog'ing after the loop, to keep even an agressive compiler from optimizing away.
Adam
+1  A: 

Apple actually provides sample code that does something similiar to what you are looking for at developer.apple.com, with the intent to highlight the performance differences between using LibXML (SAX) and CocoaXML. The focus is not on CPU performance, but assuming you can actually measure processor utilization, you could likely just scale up (repeat within your xml) the dataset that the sample downloads.

schellack
I hadn't spotted that example before - great find, thanks!
Adam