我有以下代码:
for(int i=0;i<n;i++){
funcA(i);
funcB(i);
}
我想使用多线程实现它,我认为有两种方法可以实现(在两个方面,每个线程都采用[0,n]的子范围):
1)创建一个执行这两个函数的线程类。
2)创建两个线程类:第一个执行funcA(),第二个执行funcB(),例如每个都有自己的循环,如下所示:
for(int i=0;i<n;i++){
funcA(i);
}
for(int i=0;i<n;i++){
funcB(i);
}
哪一个最好?或者它们是等价的?
答案 0 :(得分:3)
答案取决于这些功能是否相互依赖。
如果一个的执行不依赖于受另一个影响的任何变量,那么你就可以自由,甚至鼓励在不同的线程中执行这两个函数。
但是如果有一些执行顺序依赖,请注意。您可以使用互斥锁来避免一些问题,但顺序执行它们可能会更好。
编辑:正如您在评论中所述,funcB(i)
的执行取决于funcA(i)
,但{funcA(i); funcB(i)}
块彼此独立。
然后,您可以通过将(0,n)范围划分为k个线程
来并行执行多个并行执行答案 1 :(得分:2)
您可能需要考虑TBB库(http://threadingbuildingblocks.org/),它使用基于任务的并行性来消除各个迭代执行时间的可能差异。您的代码看起来像这样(使用C ++ 11)
tbb::parallel_for(0,n,[](int i){
funcA(i);
funcB(i);
});
当你必须用普通的仿函数替换lambda时,你也可以使用C ++ 03。使用TBB,您还可以将其编码为管道。
或者,使用OpenMP,您的代码只是
#pragma omp parallel for
for(int i=0;i<n;++i) {
funcA(i);
funcB(i);
}
但是这需要你的编译器支持OpenMP(clang没有),它与C ++ 11不能很好地融合。
答案 2 :(得分:1)
从你提供的两种方法中,第二种方法会更好。
原因:第一种方法意味着你要让n
个线程执行每个循环,而第二种方法是创建两个线程并分配一个线程来处理funcA
funcB
上的其他字样。然后一旦完成,继续下一次迭代并重复。这是一个更好的方法,因为你有两个线程致力于一个共同的目标,而不是n
线程。