在 Objective C 中设置 for 循环并发执行的最佳方法是什么? [英] What's the best way to set up concurrent execution of for loops in Objective C?

查看:65
本文介绍了在 Objective C 中设置 for 循环并发执行的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到过这样一个耗时的 for 循环:

I have a situation with a time-intensive for loop like this:

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

do something(i) 调用是独立的.这要求多线程.在两核机器上使用 NSOperationQueue,我可以这样做:

The do something(i) calls are independent. This cries out for multithreading. Using NSOperationQueue on a two-core machine, 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;

使用单个 NSBlock 并将循环的开始/停止值作为参数传递会更好,但与 NSOperation 一起使用的块不能有参数.这会更好的一个原因是,为不同数量的内核编码所需的体操变得非常多.

It would be much nicer to have a single NSBlock and pass the start/stop values for the loop as parameters, but blocks used with NSOperation cannot have parameters. One reason this would be nicer is that the gymnastics needed to code for varying numbers of cores gets pretty excessive.

是否有更好的方法在 iOS 中进行设置,以便可以使用参数创建单个 NSBlock(或其等效项),然后多次调用以进行并发执行?理想情况下,该技术需要是方法本地的,并且具有对局部变量的读/写访问权限(这可以通过 NSBlock 在局部变量上使用 __block 限定符实现)?

Is there a better way to set this up in iOS so a single NSBlock (or its equivalent) can be created, with parameters, and then called multiple times for concurrent execution? The technique ideally needs to be local to the method, and have read/write access to local variables (which is possible with NSBlock using the __block qualifier on local variables)?

对于那些后来出现的人,这是我最终使用的从答案和一些评论中收集的代码.

For those coming along afterwards, here's the code, gleaned from both answers and several comments, that I finally used.

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;
    });
});

推荐答案

使用并发调度队列.

    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
        });

    });

这篇关于在 Objective C 中设置 for 循环并发执行的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆