并行减少算法实现

时间:2011-07-17 09:36:08

标签: objective-c multithreading parallel-processing grand-central-dispatch objective-c-blocks

我一直在研究使用块在Objective-C中使用reduce [inject,fold,无论你想要什么调用]函数的实现,并且想知道是否有任何技术可以并行化计算所应用的函数 associative (例如整数集合的总和)?

即。是否有可能在NSArray上并行化或改进类似的东西:

- (id)reduceWithBlock:(id (^)(id memo, id obj))block andAccumulator:(id)accumulator
{
  id acc = [[accumulator copy] autorelease];

  for (id obj in self) {
    acc = block(acc, obj);
  }
  return acc;
}

使用大中央调度?

编辑:我已经进行了第二次尝试,将数组划分为更小的块并在单独的调度队列中将它们减少,但在我的测试中没有可识别的性能提升:(gist here)

2 个答案:

答案 0 :(得分:6)

您可以将dispatch_apply与Dispatch Global Queue一起用于并行化,但您的代码似乎对并发工作效率不高。因为累加器对象需要独占访问,并且它被块紧密使用,因此它将导致累加器对象的巨大锁定。

例如,即使将dispatch_apply与Dispatch Global Queue一起使用,此代码也几乎是非并发工作。

dispatch_semaphore_t sema = dispatch_semaphore_create(1);
dispatch_queue_t queue =
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply([array count], queue, ^(size_t index) {
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    acc = block(acc, [array objectAtIndex:index]);
    dispatch_semaphore_signal(sema);
});
dispatch_release(sema);

您需要拆分块和累加器实现以实现高效的并行化。

<强>编辑:

(我没有检查你的代码算法。)

dispatch_queue_t result_queue = dispatch_queue_create(NULL, NULL);

您正在使用串行队列。串行队列一次执行一个块。因此,它可能是

dispatch_queue_t result_queue =
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_queue_t result_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
/* DISPATCH_QUEUE_CONCURRENT is only available OS X 10.7/iOS 4.3 or later. */

答案 1 :(得分:1)

我实现了并行划分&amp;征服与关联函数here一起使用的算法。不幸的是,我无法从中获得任何可辨别的加速,所以我现在坚持使用简单的串行版本。我相信我的基本情况需要优化 - 我在某处读到了不等式n >= p^2应该存在,其中n是作业数量和p处理器数量。

显然,如果有人提出建议,他们会非常感激,很多时候会因阵列拆分和递归而丢失。