54
Using Concurrency To Improve The Responsiveness of iPhone Applications Danton Chin [email protected] http://iphonedeveloperjournal.com / Wednesday, September 30, 2009

Using Concurrency To Improve Responsiveness

Embed Size (px)

DESCRIPTION

Adding concurrency to your iPhone application allows your application to become more responsive to user input and usability. This session will explore the use of NSOperation and NSOperationQueue to add concurrency to iPhone applications through discussion and examples.

Citation preview

Page 1: Using Concurrency To Improve Responsiveness

Using Concurrency To Improve The

Responsiveness of iPhone Applications

Danton [email protected]://iphonedeveloperjournal.com/

Wednesday, September 30, 2009

Page 2: Using Concurrency To Improve Responsiveness

Agenda• Motivation and Predictions

• Surveying the Concurrency Landscape

• Operations and Queues

• NSInvocationOperation

• NSOperationQueue

• NSOperation

• Resources

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 3: Using Concurrency To Improve Responsiveness

Motivation and Predictions

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 4: Using Concurrency To Improve Responsiveness

Connect The Dots

April ’08 Dec ‘08

P.A. Semi purchase

Imagination Technologies:

OpenCL engineers

June ‘09

3GSWWDC

Released

Sept ’09

Dual Core Cortex-9 ARM

announced

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

GCD released as Open Source

2010

What’s next?

images from http://www.apple.com/

Wednesday, September 30, 2009

Page 5: Using Concurrency To Improve Responsiveness

Writing for Multiple Platforms

2010

netBook/iTablet?

TodayDanton Chin http://iphonedeveloperjournal.com/ September 30, 2009

images from http://www.apple.com/ image from http://www.appleinsider.com/articles/09/07/24/apples_much_anticipated_tablet_device_coming_early_next_year.html

2G, 3G, 3GS,iPod Touch

3GX ?

Wednesday, September 30, 2009

Page 6: Using Concurrency To Improve Responsiveness

PowerVR SGX

Today and Tomorrow?

Single Core

Cortex-A9 ARM

PowerVR MBX scaled up PowerVR SGX

Today 2010 ?

iPhone OS 3.1 iPhone OS 3.x

OpenCLGCDBlocks

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

3G 3GS netBook/iTablet 3GX

ARM11 Cortex-A8 ARM

Dual Core

Wednesday, September 30, 2009

Page 7: Using Concurrency To Improve Responsiveness

Surveying The Concurrency Landscape

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 8: Using Concurrency To Improve Responsiveness

Improving Performance Using Concurrency

• Multiple threads in a single-core system can be used to improve perceived performance while a multi-core system can produce real performance improvements

• Since the iPhone at this point only has one core threads are used to improve perceived performance

• Use concurrency and asynchronous functions to avoid blocking the main thread

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 9: Using Concurrency To Improve Responsiveness

Concurrency is Not Free

• Concurrent programming can be difficult and error prone

• Potential problems with race conditions, deadlocks, synchronization, and so forth

• Creation costs, memory costs

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 10: Using Concurrency To Improve Responsiveness

Grand Central Dispatch

• Introduced in Snow Leopard

• New approach to taking advantage of multiple cores

• Shifts responsibility of managing threads and the execution of jobs from the application developer to the OS using units of work (blocks) and queues

• Introduced with a language extension and new APIs

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 11: Using Concurrency To Improve Responsiveness

Blocks or Closures• Extension to Objective-C (C, C++ too) to

make it easy to define self-contained units of work or tasks

• Are Objective-C objects but look like function pointers

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

x = ^{ NSLog(@”An NSLog statement in a block”; }

Although the iPhone does not have an official implementation from Apple -- yet -- there is Plausible

Blocks an implementation from Landon Fuller at http://code.google.com/p/plblocks/

Wednesday, September 30, 2009

Page 12: Using Concurrency To Improve Responsiveness

OpenCL

• OpenCL or Open Computing Language

• Low-level C-API for general purpose parallel computations using all the computational resources available -- CPU, GPU, etc.

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 13: Using Concurrency To Improve Responsiveness

Concurrency Choices

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

Technology Description iPhone OS

Mac OS X

Operation ObjectsNSOperation objects are wrappers for tasks

NSOperationQueue objects manages the execution of tasks

Yes 10.5+

Grand Central Dispatch

Framework to transfer the responsibility of managing threads and their execution to the OS. Uses blocks and

queuesNo 10.6

Cocoa ThreadsNSThreadNSObject

Yes Yes

OpenCLC-level API to use all the computational resources

availableNo 10.6

Posix Threads or pthreads

C-based interface for creating threads Yes Yes

Wednesday, September 30, 2009

Page 14: Using Concurrency To Improve Responsiveness

Two Metrics

Operation Objects

Grand Central Dispatch

Cocoa Threads

OpenCL

Posix Threads or pthreads

Low

High

High

Low

Complexity

Abstraction Level

Mach threadskernel

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 15: Using Concurrency To Improve Responsiveness

Alternatives To Concurrency

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

Technology DescriptioniPhone

OS

Mac OS X

Asynchronous methods

Some APIs have both synchronous and asynchronous versions of the

same methodYes Yes

Idle-time notifications

Use NSNotificationQueue with a posting style of NSPostWhenIdle to receive notifications when the

run loop becomes idle

Yes Yes

Timers Use Timers to perform periodic, discrete tasks

Yes Yes

Wednesday, September 30, 2009

Page 16: Using Concurrency To Improve Responsiveness

Operations and Queues

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 17: Using Concurrency To Improve Responsiveness

Task

• Tasks are independent work units

• with no dependencies on the state or result of other tasks

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 18: Using Concurrency To Improve Responsiveness

Operations and Queues

task

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

Core Core

Queue

task

task

Wednesday, September 30, 2009

Page 19: Using Concurrency To Improve Responsiveness

Asynchronous Approach

• Look at the work performed by your application

• factor out the work that can be done concurrently vs work that must be done serially due to shared data structures

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 20: Using Concurrency To Improve Responsiveness

Class HierarchyNSObject

NSBlockOperation (Not on iPhoneOS)

NSOperation NSOperationQueue

NSInvocationOperation

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 21: Using Concurrency To Improve Responsiveness

Operation ObjectsClass Description

iPhone OS

Mac OS X

NSOperationAbstract class used to create/

define custom operation objects

Yes Yes

NSInvocationOperationLightweight operation - uses an object and a selector from your

app to create an operationYes Yes

NSBlockOperation Use this class to execute one or more blocks concurrently

No Yes

NSOperationQueue

Tasks are added to NSOperationQueue and the queue manages the execution

of the operation objects

Yes Yes

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 22: Using Concurrency To Improve Responsiveness

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

NSInvocationOperation

Wednesday, September 30, 2009

Page 23: Using Concurrency To Improve Responsiveness

NSInvocationOperation

• Concrete subclass of NSOperation

• Easiest way to define operation objects to be added to an operation queue for execution

• provided the application has a method that encapsulates the task

• creates an non-concurrent operation

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 24: Using Concurrency To Improve Responsiveness

Advantages of Using NSInvocationOperation • Quick and easy

• allows you to just use your classes which have self-contained tasks in an operation queue

• Can be dynamic

• Eliminates creating custom operation objects

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 25: Using Concurrency To Improve Responsiveness

Creating an NSInvocationOperation

target - object that defines the selector

sel - selector to be invoked; selector may take 0-1 parameters whose type must be id. The method may return void, a scalar value, or an object that can be returned as an id

arg - parameter object to be passed to the selector; specify nil if the selector does not take an argument

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

-(id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg

returns: initialized NSInvocationOperation or nil if target does not implement sel

Wednesday, September 30, 2009

Page 26: Using Concurrency To Improve Responsiveness

NSOperationQueue

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 27: Using Concurrency To Improve Responsiveness

NSOperationQueue

• Operations are added to an operation queue to be managed by the queue for execution

• Queues work with the system to determine the number of concurrent operations

• f(number of cores, system load)

• more queues more operations

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 28: Using Concurrency To Improve Responsiveness

NSOperationQueue KVO properties

property returns

operationsan array containing the operations currently in the queue

operationCount number of operations in queue

maxConcurrentOperationCountthe max number of operations the receiver can execute as an NSInteger

suspended whether queue is suspended

name queue name

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 29: Using Concurrency To Improve Responsiveness

Creating an NSOperationQueue

Create just like any other object:

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

NSOperationQueue *myQueue = [ [NSOperationQueue alloc] init];

Wednesday, September 30, 2009

Page 30: Using Concurrency To Improve Responsiveness

Adding Operations To A Queue

• An operation can only be in one queue at a time

• There is no removeOperation: method

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

Use NSOperationQueue method:

-(void)addOperation:(NSOperation *)operation

[myQueue addOperation:myOp];

Note. Docs state that you can add an array of operations but that has not been implemented in iPhone OS 3.0 only

on Mac OS 10.6Wednesday, September 30, 2009

Page 31: Using Concurrency To Improve Responsiveness

Canceling OperationsCan cancel all operations in a queue

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

-(void)cancelAllOperations

a cancel message is sent to all operations in the queue

To cancel a single operation call its cancel method

Wednesday, September 30, 2009

Page 32: Using Concurrency To Improve Responsiveness

Cancellation and KVOA “canceled” operation is considered “finished” and dependent operations still receive KVO notification that the dependency has been fulfilled

Because of this it is more common to cancel all operations rather than a single operation

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 33: Using Concurrency To Improve Responsiveness

Suspending/Resuming a Queue

Use:-(void)setSuspended:(BOOL)suspend

YES, queue stops scheduling operations for execution

NO, queue starts scheduling operations again

Suspending a queue does not suspend a currently executing operation

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 34: Using Concurrency To Improve Responsiveness

Max number of Concurrent Operations

Use

-(void)setMaxConcurrentOperationCount:(NSInteger)count

order of execution still depends on the readiness of each operation and its assigned priority

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 35: Using Concurrency To Improve Responsiveness

Demo

HelloWorldSimpleInvocation

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 36: Using Concurrency To Improve Responsiveness

NSOperation

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 37: Using Concurrency To Improve Responsiveness

NSOperation

• abstract class

• subclass to encapsulate the data and methods belonging to a task

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 38: Using Concurrency To Improve Responsiveness

KVO properties

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

isCancelled whether operation has been cancelled

isConcurrent whether the operation runs asynchronously

isExecuting whether the operation is currently executing

isFinished whether the operation is done executing

isReady whether the operation can be performed

dependencies read-only

queuePriority read-write

can use these KVO properties to control your app

Wednesday, September 30, 2009

Page 39: Using Concurrency To Improve Responsiveness

Operation Dependencies

• an operation object can have dependencies

• use dependencies to serialize execution

• operation object will not run until all its dependent operation objects have “finished executing”

• remember that a canceled operation is considered to have “finished executing”

• configure an operations dependencies before adding it to a queue

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 40: Using Concurrency To Improve Responsiveness

Adding and Removing Dependencies

Use:

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

-(void)addDependency:(NSOperation *)operation

-(void)removeDependency:(NSOperation *)operation

Wednesday, September 30, 2009

Page 41: Using Concurrency To Improve Responsiveness

Operation PrioritiesTo set the relative priority of an operation when the operation is added to an operation queue use:

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

-(void)setQueuePriority:(NSOperationQueuePriority)priority

NSOperationQueuePriorityVeryLow -8NSOperationQueuePriorityLow -4NSOperationQueuePriorityNormal 0NSOperationQueuePriorityHigh 4NSOperationQueuePriorityVeryHigh 8

Wednesday, September 30, 2009

Page 42: Using Concurrency To Improve Responsiveness

Execution Order• Operation priorities are applied to all

operations that are ready to execute

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

Op Anot ready

high priority

Op Bready

low priority

Op B will be executed before Op A

Wednesday, September 30, 2009

Page 43: Using Concurrency To Improve Responsiveness

Two Ways To Use a Subclass of NSOperation

• have an operation queue execute the operation after it is added to the queue

• manually execute the operation by calling the operation object’s start method

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 44: Using Concurrency To Improve Responsiveness

Non-Concurrent Operations

• NSOperation objects are non-concurrent by default, i.e.,

isConcurrent = NO

• Let the operation queue manage concurrency for the operation

• In a non-concurrent operation the operation’s task is performed synchronously, i.e., the operation object does not create a new thread to perform the task

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 45: Using Concurrency To Improve Responsiveness

Non-Concurrent Operations

• When a non-concurrent operation is added to an operation queue the queue creates a thread on which to run the operation which allows the operation queue to move on to the next operation

• Result:

• asynchronous execution of your operation

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 46: Using Concurrency To Improve Responsiveness

Concurrent Operations

• the operation object will manage how it wants to handle concurrency, either by

• starting a thread or

• calling an asynchronous function

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

isConcurrent = YES

In iPhone OS operation queues launch concurrent operations from the current thread

In Snow Leopard operation queues use GCD and both concurrent and non-concurrent operations are launched from a separate thread.

Wednesday, September 30, 2009

Page 47: Using Concurrency To Improve Responsiveness

Creating Custom NSOperation Objects

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

NSOperationQueue handles

concurrency

non-concurrent

custom object

if operation is always added to an operation queue then

operation is executed asynchronously

You handle concurrency

concurrent custom object

if operation needs to be run asynchronously without

adding it to an operation queue

Wednesday, September 30, 2009

Page 48: Using Concurrency To Improve Responsiveness

Creating a Non-Concurrent Subclass• Need to implement:

• init to handle any initialization for your task

• main to execute your task

• check for cancellation

• create an autorelease pool to manage objects that are autoreleased

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 49: Using Concurrency To Improve Responsiveness

Responding To Cancellations

• Responding to cancellations is voluntary so operation objects must frequently check for cancellation, clean up memory, and exit

• Use isCancelled method to check

• before doing any work

• at least once before each iteration and more frequently for long running iterations

• anywhere where it would be easy to abort Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009

Wednesday, September 30, 2009

Page 50: Using Concurrency To Improve Responsiveness

Demo

HelloWorldNonConcurrentOp

SimpleInvocationInCocoa

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 51: Using Concurrency To Improve Responsiveness

Creating a Concurrent Subclass

start• set up the thread or execution environment in which the task will run• must not call super

main implement task

isExecutingisFinished

• maintain state information for task• generate KVO notifications and be thread safe

isConcurrent • return YES

Methods to override:

Wednesday, September 30, 2009

Page 52: Using Concurrency To Improve Responsiveness

Demo

Wednesday, September 30, 2009

Page 53: Using Concurrency To Improve Responsiveness

Resources

• Apple Documentation

• Concurrency Programming Guide

• NSInvocationOperation Class Reference

• NSOperation Class Reference

• NSOperationQueue Class Reference

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009

Page 54: Using Concurrency To Improve Responsiveness

Thank You!

Have Fun With Operations and Queues!

Danton Chin

[email protected]

Danton Chin http://iphonedeveloperjournal.com/ September 30, 2009Wednesday, September 30, 2009