【发布时间】:2014-07-30 14:02:54
【问题描述】:
我尝试使用线程和模板编写合并排序的并行实现。 相关代码如下。
我已经将性能与 C++ STL 中的排序进行了比较。当没有产生线程时,我的代码比 std::sort 慢 6 倍。使用变量 maxthreads(和/或 FACTOR)我只能将性能提高一倍,因此在最好的情况下,我的速度比 std::sort 慢 3 倍。我已经在 16 核多处理器机器上尝试过代码。
htop 显示内核按预期使用,但为什么性能不足,我感觉不到整体运行时的并行性?
有错误吗?
感谢您的回复。
#define FACTOR 1
static unsigned int maxthreads = FACTOR * std::thread::hardware_concurrency();
unsigned int workers=0;
std::mutex g_mutex;
template <typename T>
std::vector<T>* mergesort_inplace_multithreading(
typename std::vector<T>::iterator* listbegin,
typename std::vector<T>::iterator *listend,
std::vector<T>* listarg)
{
if (*listbegin == *listend)
{
return listarg;
}
else if (*listend == *listbegin + 1)
{
return listarg;
}
else
{
size_t offset = std::distance(*listbegin, *listend)/2;
typename std::vector<T>::iterator listhalf = *listbegin + offset;
g_mutex.lock();
if (::workers <= maxthreads-2 and maxthreads >=2)
{
workers += 2;
g_mutex.unlock();
std::thread first_thread(mergesort_inplace_multithreading<T>, listbegin, &listhalf, listarg);
std::thread second_thread(mergesort_inplace_multithreading<T>, &listhalf, listend, listarg);
first_thread.join();
second_thread.join();
g_mutex.lock();
workers -= 2;
g_mutex.unlock();
}
else
{
g_mutex.unlock();
mergesort_inplace_multithreading<T>(listbegin, &listhalf, listarg);
mergesort_inplace_multithreading<T>(&listhalf, listend, listarg);
}
typename std::vector<T> result;
typename std::vector<T>::iterator lo_sorted_it = *listbegin;
typename std::vector<T>::iterator hi_sorted_it = listhalf;
typename std::vector<T>::iterator lo_sortedend = listhalf;
typename std::vector<T>::iterator hi_sortedend = *listend;
while (lo_sorted_it != lo_sortedend and hi_sorted_it != hi_sortedend)
{
if (*lo_sorted_it <= *hi_sorted_it)
{
result.push_back(*lo_sorted_it);
++lo_sorted_it;
}
else
{
result.push_back(*hi_sorted_it);
++hi_sorted_it;
}
}//end while
if (lo_sorted_it != lo_sortedend)
{
//assert(hi_sorted_it == hi_sortedend);
result.insert(result.end(), lo_sorted_it, lo_sortedend);
}
else
{
//assert(lo_sorted_it == lo_sortedend);
result.insert(result.end(), hi_sorted_it, hi_sortedend);
}
std::copy(result.begin(), result.end(), *listbegin);
return listarg;
}
}
int main()
{
//some tests
}
【问题讨论】:
-
我猜大部分时间都花在了产生线程和锁定/解锁互斥体上。一旦要排序的子向量小于某个阈值,您可能应该只对范围进行合并排序,而不是查看锁以发现无论如何都没有可用的线程。顺便说一句,传递
listarg并返回它有什么意义?它没有用于有用的目的,算法应该可能返回void。
标签: c++ multithreading performance recursion mergesort