Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Parallele Programmierung (DE)

Parallele Programmierung (DE)

Bei CocoaHeads Dresden

Chris Eidhof | @chriseidhof

September 11, 2013
Tweet

More Decks by Chris Eidhof | @chriseidhof

Other Decks in Technology

Transcript

  1. Nicht alles muss async sein • Schwer zu debuggen •

    Schwer zu lesen und schreiben • Fehleranfällig Sunday, September 22, 13
  2. APIs • OpenCL • pthread • NSRunLoop • NSThread •

    Grand Central Dispatch • Operation Queues Sunday, September 22, 13
  3. pthread size_t count; }; struct threadResult { uint32_t min; uint32_t

    max; }; void * findMinAndMax(void *arg) { struct threadInfo const * const info = (struct threadInfo *) arg; uint32_t min = UINT32_MAX; uint32_t max = 0; for (size_t i = 0; i < info->count; ++i) { uint32_t v = info->inputValues[i]; min = MIN(min, v); max = MAX(max, v); } free(arg); struct threadResult * const result = (struct threadResult *) malloc(sizeof(*result)); result->min = min; result->max = max; return result; } int main(int argc, const char * argv[]) { size_t const count = 1000000; uint32_t inputValues[count]; // Fill input values with random numbers: for (size_t i = 0; i < count; ++i) { inputValues[i] = arc4random(); } // Spawn 4 threads to find the minimum and maximum: size_t const threadCount = 4; pthread_t tid[threadCount]; for (size_t i = 0; i < threadCount; ++i) { struct threadInfo * const info = (struct threadInfo *) malloc(sizeof(*info)); size_t offset = (count / threadCount) * i; info->inputValues = inputValues + offset; info->count = MIN(count - offset, count / threadCount); int err = pthread_create(tid + i, NULL, &findMinAndMax, info); NSCAssert(err == 0, @"pthread_create() failed: %d", err); } // Wait for the threads to exit: struct threadResult * results[threadCount]; for (size_t i = 0; i < threadCount; ++i) { int err = pthread_join(tid[i], (void **) &(results[i])); NSCAssert(err == 0, @"pthread_join() failed: %d", err); } // Find the min and max: uint32_t min = UINT32_MAX; uint32_t max = 0; for (size_t i = 0; i < threadCount; ++i) { Sunday, September 22, 13
  4. @interface FindMinMaxThread : NSThread @property (nonatomic) NSUInteger min; @property (nonatomic)

    NSUInteger max; - (instancetype)initWithNumbers:(NSArray *)numbers; @end @implementation FindMinMaxThread { NSArray *_numbers; } - (instancetype)initWithNumbers:(NSArray *)numbers { self = [super init]; if (self) { _numbers = numbers; } return self; } - (void)main { NSUInteger min; NSUInteger max; // process the data self.min = min; self.max = max; } @end NSSet *threads = [NSMutableSet set]; NSUInteger numberCount = self.numbers.count; NSUInteger threadCount = 4; for (NSUInteger i = 0; i < threadCount; i++) { NSUInteger offset = (count / threadCount) * i; NSUInteger count = MIN(numberCount - offset, numberCount / threadCount); NSRange range = NSMakeRange(offset, count); NSArray *subset = [self.numbers subarrayWithRange:range]; FindMinMaxThread *thread = [[FindMinMaxThread alloc] initWithNumbers:subset]; [threads addObject:thread]; [thread start]; } NSThread Sunday, September 22, 13
  5. UI Aktualisieren dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(defaultQueue, ^{ [self

    expensiveBackgroundCode]; dispatch_async(dispatch_get_main_queue(), ^{ self.label.text = @"Done"; }); }); Sunday, September 22, 13
  6. Main context aktualisieren [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification object:nil queue:nil usingBlock:^(NSNotification* note)

    { NSManagedObjectContext *moc = mainManagedObjectContext; if (note.object != moc) { [moc performBlock:^(){ [moc mergeChangesFromContextDidSaveNotification:note]; }]; } }]; Sunday, September 22, 13
  7. Es gibt noch immer ein Lock Du kannst aber zwei

    Persistent Store Coordinators verwenden Sunday, September 22, 13
  8. UI im Hintergrund [operationQueue addOperationWithBlock:^{ NSNumber* result = findLargestMersennePrime(); [[NSOperationQueue

    mainQueue] addOperationWithBlock:^{ self.textLabel.text = [result stringValue]; }]; }]; Sunday, September 22, 13
  9. Parallel zeichnen UIGraphicsBeginImageContextWithOptions(size, NO, 0); // drawing code here UIImage

    *i = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return i; Sunday, September 22, 13
  10. Parallel zeichnen • Nur wenn es notwendig ist • Vielleicht

    kannst du es vermeiden • WWDC 2012 - Building Concurrent User Interfaces on iOS Sunday, September 22, 13