I have some code that runs slowly when I test it on an iPhone 4. I am thinking about researching Grand Central Despatch and using a background thread for some tasks. However, I understand that the iPhone 4 is a single core device. Does this mean there will be no benefit on this device to using a background thread?
I couldn't find much in Apple's documentation about different device capabilities in this regard and am new to background processing.
Yes as long as its running iOS 4 or later. GCD is a good design in that it can be used equally well on single core machines all the way up to 16 Core Mac Pro's. In fact Apple emphasized this when they introduced GCD. If your code is well written it should work equally well on a single core iPhone as well as multicore iOS Devices out there. Theoretically you should see performance improvements on multicore devices over the single core devices.
It all depends what your code is actually doing. If your code is targeted to calculate only one thing without stopping there is no benefit of using multithreading on one core cpu in terms of performance. If however some of your tasks are waiting for something like network data, waiting on disk operation, sleeping etc. then your other threads might be using that time to do something useful even on one core cpu. Generally if you are interacting with UI then it is recommended to do time consuming tasks in background so you won't block user interface thus providing better experience for the end user.
Related
I'm programming an app on ios with xcode and I after a lot of work I found out that the functionality is really dependant on the accuracy of the methods calls.
Calling them one line after the other in the code doesn't help, they're still called at up tp 150 ms difference after each other.
So I need to make two methods run at the minimal time difference, hence "at the same time".
These two tasks I'm performing are actually audio and video ones so I understand it might include also in-process latency and delays, so I was wondering maybe you guys would have any isight on how to sync an audio task and a video task so that they start running together, with a very tiny time gap.
I tried using dispatch queues and stuff like that, but they don't work.
I'll be happy to elaborate if I wasn't clear enough.
Thanks!
You can't make an interrupt driven, multi-tasking OS behave like a realtime OS.
It just doesn't work that way.
You'll need to use the various multimedia APIs to set up a context of playback where the audio and video are synchronized within (which I don't know).
Apple has APIs and documentation to go with them on syncing audio and video. http://developer.apple.com
Obviously calling methods sequentially (serially) won't do what you are asking since each method call will take some finite amount of time, during which time the subsequent methods will be blocked.
To run multiple general-purpose tasks concurrently (potentially truly simultaneously on a modern multi-core device) you do need threading via "dispatch queues and stuff like that." GCD most certainly does work, so you are going to need to elaborate on what you mean by "they don't work."
But this is all probably for naught, because you aren't talking about general-purpose tasks. If you are handling audio and video tasks, you really shouldn't do all this with your own code on the CPU; you need hardware acceleration, and Apple provides frameworks to help. I'd probably start by taking a look at the AV Foundation framework, then, depending on what you are trying to do (you didn't really say in your question...) take a look at, variously, OpenAL, Core Video, and Core Audio. (There's a book out on the latter that's getting rave reviews, but I haven't seen it myself and, truth be told, I'm not an A/V developer.)
As you may know, in any multitasking environment (especially on single core devices), you'll not be able to have guarantees on timing between statements you're executing.
However, since you're mentioning playback of audio and video, Apple does provide some fundamentals that can accomplish this through its frameworks.
AVSynchronizedlayer - If some of your video or audio can playback from an AVPlayerItem (which supports a variety of formats), you can build a tree of other events which are synchronized with it, from keyframe animations to other AVPlayerItems.
If multiple audio tracks are what you're looking to in particular, there are some simpler constructs in Core Audio to do that too.
If you can give a more specific example of your needs someone may be able to provide additional ideas.
I have an iPad app that has a process for downloading lots of map files (a couple of gigs of data and 10s of thousands of files).
In my most recent test release, the device will sometimes reboot during the download process, (downloads can take a couple of hours).
When the app reboots, it does not leave a crash report. We have observed this behavior on both an iPad 1 and an iPad 2 running 4.3.3.
The only thing I can think of is we increased the max concurrent threads from 4 to 20 for doing these downloads.
Completely exhausting the system memory triggers a hard reboot of the device. This used to be more common in iPhone OS 2.0, running on the limited hardware of the initial iPhones and iPod touches. In recent OS versions, Apple has more rigidly enforced the hard kill of your application when it exceeds its memory ceiling, so it's become much harder to do this. Also, the devices have much more memory than they used to.
One way that you can sometimes do this is by loading many large textures or other graphical components that may not be immediately identified as memory used by your application. I've been able to cause a system reboot when loading a pile of data onto the GPU in a tight loop. You may be encountering something similar here.
I doubt that this is related to the number of active threads you have going, although they probably make it easier for you to dump a mess of data into memory before the system can kill your application.
As an aside, rather than having piles of threads, which consume resources, have you looked at using GCD or a queue-based framework like ASIHTTPRequest? These might be more efficient for your application, yet still provide the concurrency you need.
Your app is crashing most likely due to memory management. Since you are downloading several GB's of data, maybe you are running out of disk space? I am not sure why it would take your device several hours to reboot.
Try posting some code.
Have you debugged in Instruments? This will show you if allocations are rising and filling memory. If you are attempting to load these GBs into memory, then of course your going to experience a crash.
Also, have you looked at dispatch_apply instead of threads? GCD automatically distributes and increases/reduces the threads it uses based on load. This way you don't have to manage this yourself. It might be worth a shot.
I can't seem to find this anywhere, but I'm sure there must be an answer...
How many simultaneous HTTP connections can an iphone app service? In other words, if I build and run a bunch of NSURLConnections asynchronously, how many can be in flight before it starts queuing them?
Also, is there a method to check how many threads are available and/or in use programmatically?
I'm trying to write an intelligent pre-fetching engine, and these limits (if any) would be useful information.
The iPhone doesn't start queuing NSURConnections. That's totally your responsibility. The iPhone will start all your asynchronous NSURLConnections in parallel. The only thing that will stop it is your memory :) I recently implemented a connection pool (my solution was based on NSOperationQueue) just because of that. Now I can control parallel connections and my app doesn't crash when loading hundreds of avatar images.
About your second question. I actually don't know about a way to get the list of current threads. I had a look at NSThread API but no sign of an API for that..
So the reason I assumed there may be a simultaneous connection limit at the mobile OS level is because many mobile browsers enforce one. There are techniques for speeding up loading speed of the mobile version of your website by ensuring that there are as few additional content fetches as possible. Images are the main culprit, but css files, javascript files, etc all require an additional connection.
In mobile, setting up and tearing down a connection is much more expensive than a single connection with more data, and one technique for improving page load performance is embedding your CSS and javascript in the page itself.
It sounds like this limitation may not exist in the OS itself, at least on the iphone platform.
As far as an answer to this question, I found this post that discusses the practical limitations of simultaneous connections. It's not a hard limit, but I think it answers the point of the question.
Background threads consuming 100% CPU on iPhone 3GS causes latent main thread
Something I've noticed about every iPhone app I've tried is that they all have places where they seem very slow and unresponsive. It's true of the games, the free apps, the pricy, popular, "professional" apps, and even a couple of Apple's built-in apps. They all seem to have places where they take many seconds or even a minute to respond to screen touches; bog down and show a spinning beachball for seconds at a time; "queue up" input so that a button press appears to ignored only to actually do something ten seconds later like a poorly made DVR; and lock up for so long that the OS watchdog just kills them.
Because these perf issues are so widespread it seems to me that there must be some common performance pitfalls some system gotchas that are coming up over and over again for lots of different people. I'm not an iPhone developer myself, so I'm canvassing the community's opinions:
What are the most common performance mistakes on the iPhone?
Or, what human factors of iPhone development make it too easy to ship with poor performance?
I think that the performance issues are a matter of perception. Apple has employed animation throughout every aspect of the iPhone's interface, which produces the impression of a smooth, responsive device. The slowdowns you refer to appear much worse than they might be because they stand out from the otherwise fluid interface. If you compare the total execution times of these tasks to similar applications on other mobile devices, I'd guess that the iPhone implementations would still come out near the top.
There's always room for improvement, though, and I'd expect that many of the tricks people have learned in the last year will lead to faster, more responsive applications. Even the development tools themselves are advancing, and that should make it easier to diagnose and deal with performance bottleneck. I know I keep learning new tricks every week for squeezing a little more out of the CPU, GPU, or onboard memory.
I'm still surprised by how quickly people have shifted their expectations as to what handheld devices can do. I'm the author of an open source application called Molecules, which does 3-D molecular modeling on the iPhone. A little over ten years ago, these types of renderings were being done on dedicated SGI Irix workstations. A few weeks after the launch of the App Store, I started receiving emails from people complaining that the application was a little jerky when they tried to manipulate molecules with over 20,000 atoms in their structure. In a very short time, people went from treating these devices like phones and music players to viewing them as portable computers.
Memory management is a bit of a beast.
But I think the biggest problem is this: How long can you afford to polish a product that will sell for 99 cents and compete with tens of thousands of other apps and has unknown revenue potential in a rapidly changing market?
The iPhone is a GREAT little device, but the competition for mindshare is fierce and expensive.
As mentioned before the ratio of profit/time spent in development would explain it.
More technically, I would say that the lag you see is created on startup when apps are either getting data over network or calling home to check for updates and so on. Additionaly it may be created with initializing application like loading large amounts of data from database/files, loading gui components and images, drawing and so on.
Similar to memory management this all can be solved by designing operations to run in background, lazy loading and so on but that requires more time, time is money, you don't get much for 99C app which may or may not sell at all.
It is interesting that so many times it is pointed out in professional articles (no ref...) that we should not care anymore about memory and speed because desktops are getting faster with more memory. What people tend to forget is that at the same we're trying to squeeze more power from smaller and smaller devices that are running with smaller resources.
Most web pages for example are nowadays designed to load huge amounts of animations and images and, unlike some, are not tweaked at all for performance but do just okay on desktops. Those web pages have no chance of loading on mobile device. The same goes for applications, designing a fat big framework (or gui widget library) for desktop will make it ultra difficult to port the functionality to sleek mobile device be it iphone, some fruit berry and what not.
As in other things in life, you get what you paid for.
My 99C.
I think the biggest issue is that it's impossible to determine the speed of an app without actually running it on the device. Developers perform most of the basic app testing in the iPhone Simulator (which can run up to 1000x times as fast in my experience). Some operations that take a split second in the simulator might require a progress indicator on the phone, and by the time you realize, it would require a lot of effort to go back and add (and in some cases thread) the operation in question. As Noshredna pointed out, it's generally a 99c app.
The iPhone's processor is also just fundamentally limiting. I've seen several nice looking apps that try to do very impressive things without accepting the constraints of the platform.
This is sort of a side note, and I don't want to start the mobile platform wars, but I've found that iPhone Apps are generally more responsive than Android apps...
Well, because maybe you deleated the app and install again because something wrong happens to it, so it must took awhile, it took me about 2 or 3 days to get full loaded so be patient, it will come eventually. Also maybe your iphone doesn't have any more spaces for your app, or your app is quite heavy, try and delete other apps so it will have rooms.
I was told that the iPhone does not support multitasking and multithreading. This did not make sense to me, so I tested on the simulator: pthreads works, fork() doesn't.
This result does make sense to me, but now I'm not sure: will the pthread library also work on the real device?
Thanks.
Multithreading will work. It's multitasking that won't. The iphone won't let more than one third party application run at once. That reasoning makes fork live outside of the application's sandbox.
You can create threads to poll sockets, read files, handle an AI player all you want, or until the performance gains start to go away.
Yes, the pthread library will work on the iPhone. Alternately you can use Cocoa-native threads with NSThread. Multitasking will not work, as Apple is explicitly restricting that.
Most likely.
Multitasking is disabled by default to prevent apps from spawning a bunch of processes and either slowing down the iPhone or doing malicious things.
The iPhones CPU really isn't that fast, but by only running 1 program at a time, it seems speedy. Multitasking would introduce a lot of overhead and other problems which would slow down the iPhone.
I'm not actually sure about multithreading, but since threads are contained to your own process, it seems likely that they would work.
And as you said, pthreads work and fork() doesn't, so its logical it would work on the real one as well.
Multithreading is very much possible - the iPhone actually uses the same Cocoa threading APIs that are available on the Mac. I write a collaborative drawing app that uses 6 threads to handle drawing, network communication, etc. I think creating too many threads would be a bad idea, since the iPhone only has one processor. They work very well in my experience, though!