C++ 并行快速排序:使用boostbind的递归?

C++ 并行快速排序:使用boostbind的递归?,c++,multithreading,boost,C++,Multithreading,Boost,我正在努力使快速排序并行,线程是第一次尝试。非线程版本排序正确,但线程版本排序不正确(这并不奇怪)。我发现有趣的是,当我删除线程但保留boost::bind调用时,它仍然不起作用。如果boost::bind不是我想要的,请提供一个建议。绑定似乎是使我的函数与boost线程一起工作的最简单(或唯一)的方法 void Quicksort( fVec &Array, const int Left, const int Right ) { if( Right <= Left )

我正在努力使快速排序并行,线程是第一次尝试。非线程版本排序正确,但线程版本排序不正确(这并不奇怪)。我发现有趣的是,当我删除线程但保留boost::bind调用时,它仍然不起作用。如果boost::bind不是我想要的,请提供一个建议。绑定似乎是使我的函数与boost线程一起工作的最简单(或唯一)的方法

void Quicksort( fVec &Array, const int Left, const int Right )
{
    if( Right <= Left )
        return;

    int pivot = Left;
    const int pivotNewIndex = Partition( Array, Left, Right, pivot );

    // These function calls make it work fine
    //Quicksort( Array, Left, pivotNewIndex - 1 );
    //Quicksort( Array, pivotNewIndex + 1, Right );

    // boost::bind calls only swaps one element, doesn't actually sort
    boost::bind( &Quicksort, Array, Left, pivotNewIndex - 1 )();
    boost::bind( &Quicksort, Array, pivotNewIndex + 1, Right )();

    // threaded version that doesn't work, same as above
    //boost::thread threadA( boost::bind( &Quicksort, Array, Left, pivotNewIndex - 1 ) );
    //threadA.join();
    //boost::thread threadB( boost::bind( &Quicksort, Array, pivotNewIndex + 1, Right ) );
    //threadB.join();
}
void快速排序(fVec和数组,左常量整型,右常量整型)
{

如果(RightBoost bind或多或少创建了一个函子,调用该函子时,它将使用所需的参数调用所需的函数。在这种情况下,您正在创建函子,但从未调用它。请尝试:

boost::bind( &Quicksort, Array, Left, pivotNewIndex - 1 )();
boost::bind( &Quicksort, Array, pivotNewIndex + 1, Right )();
我猜是第一个参数把事情搞砸了。我认为bind要求参数是可复制的,而引用并不是真的,它可能是在创建一个副本并将引用传递给该副本,这就是为什么没有任何变化。请尝试:

boost::bind( &Quicksort, boost::ref(Array), Left, pivotNewIndex - 1 )();
boost::bind( &Quicksort, boost::ref(Array), pivotNewIndex + 1, Right )();
了解fVec是什么以及为什么不向正在排序的数组传递指针会有所帮助

还要注意的是,这种线程方法可能不会提供太多的加速,因为当您进行非常小的排序时,启动和调度新线程的开销远远大于其好处(另外,您将创建大量的线程,这是不好的)。您真正需要的是一个线程池,该线程池在某个最佳大小的块或更大的块上运行,并具有固定数量的线程。当达到小于限制的大小时,它将按顺序执行所有操作(对于更小的块,您显然希望从快速排序更改为插入排序)


另外请注意,您加入的顺序无论如何都会导致串行执行…您希望在启动两个线程后加入两个线程。

Boost bind或多或少创建一个函子,调用该函子时,将使用所需参数调用所需函数。在这种情况下,您正在创建函子,但从未调用它。请尝试:

boost::bind( &Quicksort, Array, Left, pivotNewIndex - 1 )();
boost::bind( &Quicksort, Array, pivotNewIndex + 1, Right )();
我猜是第一个参数把事情搞砸了。我认为bind要求参数是可复制的,而引用并不是真的,它可能是在创建一个副本并将引用传递给该副本,这就是为什么没有任何变化。请尝试:

boost::bind( &Quicksort, boost::ref(Array), Left, pivotNewIndex - 1 )();
boost::bind( &Quicksort, boost::ref(Array), pivotNewIndex + 1, Right )();
了解fVec是什么以及为什么不向正在排序的数组传递指针会有所帮助

还要注意的是,这种线程方法可能不会提供太多的加速,因为当您进行非常小的排序时,启动和调度新线程的开销远远大于其好处(另外,您将创建大量的线程,这是不好的)。您真正需要的是一个线程池,该线程池在某个最佳大小的块或更大的块上运行,并具有固定数量的线程。当达到小于限制的大小时,它将按顺序执行所有操作(对于更小的块,您显然希望从快速排序更改为插入排序)

另外请注意,您加入的顺序会导致串行执行……您希望在启动两个线程后加入这两个线程