我一直在研究使用块在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)答案 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处理器数量。
显然,如果有人提出建议,他们会非常感激,很多时候会因阵列拆分和递归而丢失。