使用两个语句并行化while循环(Floyd循环检测算法)

时间:2016-02-07 07:56:27

标签: c++ multithreading algorithm performance openmp

我会尝试并行以下简单 sections循环到两个线程 OpenMP (我的第一个用这种技术行走的尝试)。我尝试过同时使用taskswhile ( tortoise != hare ) { tortoise = f ( tortoise ); hare = f ( f ( hare ) ); } 。尽管我把它分成了两个线程并产生了正确的结果,但是性能是不可接受的慢。

f

注意: const &是函数对象的T operator()(const T &r)(即它有一个operator()

d实现如下(T operator() ( const T &r ) const { return ( ( r % d ) * 10 ); } 函数对象的成员变量):

team

我的第一个想法是创建线程的开销。所以我在封闭函数的最开始创建了while(它本身只被调用一次,而#pragma omp ... - 循环本身上面可以有很多迭代(它是{{的一部分) 3}})。

我在这里省略了所有while次尝试,因为所有这些尝试都导致了糟糕的表现。

编辑:

根据 @templatetypedef 的回答,我尝试了布伦特算法。因为我需要注入一些计算在 Floyd的第二和第三{{1}} - 循环(构建预循环的数字数组和循环值) ,以及使用Horner方案计算多项式) Brent 为我提供了无需添加此代码的要点。因此我更喜欢 Floyd 。完整的代码可以找到Floyd cycle detection algorithm

1 个答案:

答案 0 :(得分:4)

我认为这里的问题是您尝试并行化的代码不能很好地并行化。可以这样想:每个线程需要进行大约十几个算术运算来推进其指针,但是然后需要与另一个线程同步以确认值不相同并且不能进行任何部分进展直到两个线程都完成简单地锁定或解锁互斥锁的成本是about 17ns,这可能是评估其中一个乌龟或野兔步骤需要多长时间。因此,每个线程最终可能会完成与单个循环迭代相同的工作量 - 并且可能更多 - 所以我非常怀疑你会以这种方式获得加速。

现在,可能有用的方法是使用像布伦特的循环寻找算法这样的算法,这种算法比Floyd算法的比较少,并且通常会收敛得更快。这很可能会让你更快地找到周期。