Within three years, nearly 75 percent of smartphones and tablets will have a multicore processor, predicts In-Stat, a research firm. This trend is no surprise, considering how mobile devices are increasingly handling multiple tasks simultaneously, such as serving as a videoconferencing endpoint while downloading email in the background and running an antimalware scan.
Today’s commercially available dual-core mobile devices include Apple’s iPad 2, HTC’s EVO 3D and Samsung’s Galaxy Tab, and some vendors have announced quad-core processors that will begin shipping next year. Operating systems are the other half of the multicore equation. Android and iOS, which are No. 1 and No. 2 in terms of U.S. market share, already support multicore processors.
“IOS and Android are, at their core, based on multithreaded operating systems,” says Geoff Kratz, chief scientist at FarWest Software, a consultancy that specializes in system design. “Android is basically Linux, and iOS is based on Mac OS, which in turn is based on BSD UNIX. That means that, out of the box, these systems are built to support multicore/multi-CPU systems and multithreaded apps.”
For enterprise developers, what all this means is that it’s time to get up-to-speed on programming for mobile multicore devices. That process starts with understanding multicore’s benefits — and why they don’t always apply.
Divide and Conquer
Performance is arguably multicore’s biggest and most obvious benefit. But that benefit doesn’t apply across the board; not all apps use multithreading. So when developing an app, an important first step is to determine what can be done in parallel.
“This type of programming can be tricky at first, but once you get used to it and thinking about it, it becomes straightforward,” says Kratz. “For multithreaded programming, the important concepts to understand are queues (for inter-thread communications) and the various types of locks you can use to protect memory (like mutexes, spin locks and read-write locks).”
It’s also important to protect shared data.
“Most programmers new to multithreaded programming assume things like a simple assignment to a variable (e.g., setting a “long” variable to “1”) is atomic, but unfortunately it often isn’t,” says Kratz. “That means that one thread could be setting a variable to some value, and another thread catches it halfway through the write, getting back a nonsense value.”
It’s here that hardware fragmentation can compound the problem. For example, not all platforms handle atomic assignments. So an app might run flawlessly on an enterprise’s installed base of mobile devices, only to have problems arise when non-atomic hardware is added to the mix.
“Using mutexes (which allow exclusive access to a variable) or read/write locks (which allow multiple threads to read the data, but lock everyone out when a thread wants to write) are the two most common approaches, and mutexes are by far the most common,” says Kratz. “For Android programmers, this is easily done using the ‘synchronized’ construct in the Java language, protecting some of the code paths so only one thread at a time can use it.”
For iOS, options include using POSIX mutexes, the NSLock class or the @synchronized directive.
“Ideally, a programmer should minimize the amount of data shared between threads to the absolute bare minimum,” says Kratz. “It helps with performance and, more importantly, makes the app simpler and easier to understand — and less liable to errors as a result.”
No Free Power-lunch
As the installed base of mobile multicore devices grows, it doesn’t mean developers can now ignore power consumption. Just the opposite: If multicore enables things that convince more enterprises to increase their usage of smartphones and tablets, then they’re also going to expect these devices to be able to run for an entire workday between charges. So use the extra horsepower efficiently, such as by managing queues.
“You want to use a queue construct that allows anything reading from the queue to wait efficiently for the next item on the queue,” says Kratz. “If there is nothing on the queue, then the threads should basically go idle and use no CPU. If the chosen queue forces you to poll and repeatedly go back and read the queue to see if there is data on it, then that results in CPU effort for no gain, and all you’ve done is use up power and generate heat. If a programmer has no choice but to poll, then I would recommend adding a small sleep between polling attempts where possible, to keep the CPU load down a bit.”
When it comes to power management, many best practices from the single-core world still apply to multicore. For example, a device’s radios — not just cellular, but GPS and Wi-Fi too — are among the biggest power-draws. So even though multicore means an app can sit in the background and use a radio — such as a navigation app constantly updating nearby restaurants and ATMs — consider whether that’s the most efficient use of battery resources.
“For some apps, like a turn-by-turn navigation app, it makes sense that it wants the highest-resolution location as frequently as possible,” says Kratz. “But for some apps, a more coarse location and far less frequent updates may be sufficient and will help preserve battery.
“There may be times where an app will adapt its use of the GPS, depending on if the device is plugged into power or not. In this case, if you are plugged into an external power source, then the app can dial up the resolution and update frequency. When the device is unplugged, the app could then dial it back, conserving power and still working in a useful fashion.”
Photo Credit: @iStockphoto.com/skodonnell