我一直在测试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;
}
答案 0 :(得分:0)
请阅读this。我使用了选项:
CFLAGS += -fopenmp -Ofast -march=native
他们加快了您的测试速度,但很抱歉,我说我没有足够的内核来重现您的结果。无论如何,允许本机CPU操作应该影响数据访问序列化。