What is the best way to set up simultaneous execution of loops in Objective-C?

I have a situation with a time consuming loop:

int sum = 0;
for (int i = 0; i < max; ++i)
   sum += dosomething(i);

Do calls are something(i)independent. It screams for multithreading. Using NSOperationQueue on a dual-core computer, I can do this:

int __block midpoint;
int __block sum1;
int __block sum2;
midpoint = max/2;
sum1 = 0;
sum2 = 0;

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

NSOperation *operation = [NSBlockOperation blockOperationWithBlock: ^{
    for (int i = 0; i < midpoint; ++i)
        sum1 += dosomething(i);
}];
[queue addOperation: operation];

operation = [NSBlockOperation blockOperationWithBlock: ^{
    for (int i = midpoint; i < lines.count; ++i)
        sum2 += dosomething(i);
}];
[queue addOperation: operation];

[queue waitUntilAllOperationsAreFinished];
int sum = sum1 + sum2;

It would be much better to have one NSBlock and pass start / stop values ​​for the loop as parameters, but the blocks used with NSOperation cannot have parameters. One of the reasons this would be better is because the gymnastics needed to encode a different number of cores becomes quite excessive.

iOS, NSBlock ( ) , ? / ( NSBlock __block )?


, , , , .

dispatch_queue_t coreQueue = dispatch_queue_create("coreQueue", DISPATCH_QUEUE_CONCURRENT);
int __block count = 0;
int processorCount = (int) [[NSProcessInfo processInfo] processorCount];

dispatch_apply(processorCount, coreQueue, ^(size_t i) {
    int localCount = 0;
    int imax = (i + 1)*max/processorCount;
    if (i + 1 == processorCount)
        imax = lines.count;
    int imin = i*max/processorCount;
    for (int j = imin; j < imax; ++j)
        localCount += dosomething(j);

    // The results array should only be accessed from the main queue.
    dispatch_async(dispatch_get_main_queue(), ^{
        count += localCount;
    });
});
0
2

.

    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        [self doAnExpensiveOperation];
    });
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        [self doAnotherExpensiveOperation];
    });
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{

        dispatch_async(dispatch_get_main_queue(), ^{

            // called when both have finished.
            // calculate sum here
        });

    });
0

, NSEnumerationConcurren:

, , , :

[myArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) 
{

//do something

}];

Apple NSEnumerationConcurrent

, , !

dispatch_apply:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_apply(count, queue, ^(size_t i) {
printf("%u\n",i); //Do expensive operation here.
});
+2

All Articles