与Mergesort相比,为什么GNU并行Quicksort如此之慢?

时间:2014-06-18 16:28:01

标签: c++ parallel-processing openmp gnu quicksort

我一直在测试C ++标准库中OpenMP GNU并行排序算法的实用性,并发现并行Quicksort算法明显慢于Mergesort算法。在我的电脑上,Mergesort需要52秒来对80亿个整数的矢量进行排序,而Quicksort需要不到8分钟。对CPU使用率进行不科学的检查表明,快速排序在大约20秒内充分利用了并行性,然后其余的运行只使用了2个线程(或%200 CPU)。

我检查了算法的源代码,虽然我无法理解所有这些。如果这不是原因,有人可能会向我解释为什么算法与mergesort相比这么慢?我原本想过联系算法的原始作者,但是先考虑一下这里的问题。

以下是一些希望演示此问题的代码,如果您没有运行所需的大量资源,可以在命令行中指定要排序的元素数量。我正在使用GCC 4.9:

#include <vector>
#include <parallel/algorithm>
#include <boost/date_time.hpp>
#include <stdlib.h>
#include <iostream>
#include <omp.h>
#include <sstream>

const size_t DEFAULT_NUMBER = 8000000000;
int main(int argc, char **argv)
{
    size_t number_of_elements = DEFAULT_NUMBER;
    if(argc > 1 && argv[1] != 0)
    {   
        number_of_elements = atoi(argv[1]);
    }   
    std::vector<int> elements(number_of_elements);
    srandom(10);
    for(size_t i = 0; i < elements.size(); i++)
    {   
        elements[i] = random();
    }   

    boost::posix_time::ptime time = boost::posix_time::second_clock::local_time();
    __gnu_parallel::sort(elements.begin(), elements.end(), __gnu_parallel::multiway_mergesort_tag());
    std::cout << "Mergesort took: " << boost::posix_time::to_simple_string(boost::posix_time::second_clock::local_time() - time) <<  std::endl;

    //Repopulate vector with random elements
    srandom(10);
    for(size_t i = 0; i < elements.size(); i++)
    {   
        elements[i] = random();
    }   
    time = boost::posix_time::second_clock::local_time();
    __gnu_parallel::sort(elements.begin(), elements.end(), __gnu_parallel::quicksort_tag());
    std::cout << "Quicksort took: " << boost::posix_time::to_simple_string(boost::posix_time::second_clock::local_time() - time) <<  std::endl;
}

1 个答案:

答案 0 :(得分:0)

请阅读this。我使用了选项:

CFLAGS += -fopenmp -Ofast -march=native

他们加快了您的测试速度,但很抱歉,我说我没有足够的内核来重现您的结果。无论如何,允许本机CPU操作应该影响数据访问序列化。