Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么GNU并行快速排序比合并排序慢? 我已经在C++标准库中测试OpenMP GNU并行排序算法的实用性,发现并行快速排序算法比合并算法快得多。在我的电脑上,Mergesort需要52秒来排序80亿个整数的向量,而Quicksort只需要不到8分钟。对其CPU使用情况的不科学检查表明,quicksort在大约20秒的时间内充分利用了并行性,然后它的其余运行只使用了2个线程(或%200 CPU)_C++_Parallel Processing_Openmp_Gnu_Quicksort - Fatal编程技术网

为什么GNU并行快速排序比合并排序慢? 我已经在C++标准库中测试OpenMP GNU并行排序算法的实用性,发现并行快速排序算法比合并算法快得多。在我的电脑上,Mergesort需要52秒来排序80亿个整数的向量,而Quicksort只需要不到8分钟。对其CPU使用情况的不科学检查表明,quicksort在大约20秒的时间内充分利用了并行性,然后它的其余运行只使用了2个线程(或%200 CPU)

为什么GNU并行快速排序比合并排序慢? 我已经在C++标准库中测试OpenMP GNU并行排序算法的实用性,发现并行快速排序算法比合并算法快得多。在我的电脑上,Mergesort需要52秒来排序80亿个整数的向量,而Quicksort只需要不到8分钟。对其CPU使用情况的不科学检查表明,quicksort在大约20秒的时间内充分利用了并行性,然后它的其余运行只使用了2个线程(或%200 CPU),c++,parallel-processing,openmp,gnu,quicksort,C++,Parallel Processing,Openmp,Gnu,Quicksort,我检查了算法的源代码,虽然我不能完全理解它。如果这不是原因,也许有人能向我解释一下为什么与mergesort相比,该算法如此缓慢?我本想联系算法的原始作者,但认为先在这里尝试更为礼貌 下面是一些代码,希望能够演示这个问题,如果我的运行不需要大量资源,您可以在命令行上指定要排序的元素数。我使用的是GCC 4.9: #include <vector> #include <parallel/algorithm> #include <boost/date_time.hpp&

我检查了算法的源代码,虽然我不能完全理解它。如果这不是原因,也许有人能向我解释一下为什么与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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
常量大小默认值=800000000;
int main(int argc,字符**argv)
{
元素的大小\u t编号\u=默认\u编号;
如果(argc>1&&argv[1]!=0)
{   
元素的数量=原子(argv[1]);
}   
std::向量元素(元素的数量);
随机数(10);
对于(size_t i=0;i
CFLAGS += -fopenmp -Ofast -march=native

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

我怀疑是因为分页和内存使用模式。您是否尝试使用不同的向量大小运行实验,并查看性能如何变化?我想是的因为快速排序一直使用同一个数组,所以线程需要序列化才能访问数组。MergeSort复制数组的一半,对它们进行排序,然后将它们合并,所以不需要数据访问序列化。@Svalorzen我尝试的数据是10亿个元素,20亿个,40亿个。1亿个元素是9秒OND代表Mergesort,54秒代表Quicksort,所以差距确实扩大了。@user3751940您是否尝试过以百万计的1k、10k、100k等等?您知道,以数十亿计的速度启动没有多大意义。您需要了解整个情况。您的内存大小是多少?我花了大量时间阅读它。有关排序及其标记的信息s似乎与我得到的编译错误不一致。无论如何,我最初通过-O2进行了优化,我添加了您的选项,但没有获得任何有意义的性能好处。您运行的是哪种机器/操作系统?我仍然无法复制您的结果-在我的机器上是快速排序(特别是
平衡\u快速排序
版本)工作速度比MergeSort(排序40亿字节)快。但是,我看到了您在任务管理器中谈论的效果-CPU#1是100%,CPU#2是50%。可能是因为征服步骤中使用的线程数量有限-我看到了
#pragma omp parallel num#u threads(2)
在两个版本的快速排序中。我使用的是双Intel Xeon E5-2670(总共16个物理内核)使用CentOS 6.4。我有120GB的RAM,所以我知道你是否会发现很难重现我的结果。我检查了代码并看到了这一点,但我一定是在非稳定排序中遗漏了它。如果前面提到的线程限制是原因,为什么会在征服阶段故意这样做?我想你在我的评论中是对的问题?