需要有关多线程合并排序的建议

时间:2015-09-27 08:51:21

标签: c++ multithreading algorithm sorting

基本上,如果合并排序中的列表数等于计算机中的核心数,它将生成一个线程来对每个列表进行排序。它目前正在运行,但我面临的问题是它实际上需要比正常的合并排序花费更长的时间。它需要更长的时间,因为而不是产生让我们同时说4个线程,它会产生一个线程,它会在继续调用下一个线程之前完成整个过程。下面是我写的代码,它可以工作,但由于我上面提到的问题它再次变慢。如果有人对排序算法中使用线程有任何熟悉,那么任何反馈都会非常感激。 FURTHERMORE,这不是家庭作业,我的课程项目是设计一个正常的合并排序,我只是试图尝试使用该语言并尝试不同的东西。

void MergeSortThreading(int low, int high, int* source, int* destination, int count)
{
if (low == high)
    return;
int mid = (low + high) / 2;
int start_1 = low, end_1 = mid, start_2 = (mid + 1), end_2 = high, dest = start_1;

if (pow(2, count) == cores())
{
    thread* processes = new thread[cores()];
    int j = 1;
    for (int i = 0; i < cores(); i++)
    {
        processes[i] = thread(MergeSortThreading, j, (j + (high)), destination, source, 1000);
        j += (high - 1);
    }

    for (int i = 0; i < cores(); i++)
        processes[i].join();
}

MergeSortThreading(low, mid, destination, source, ++count);
MergeSortThreading((mid + 1), high, destination, source, 150);

while (start_1 <= end_1 && start_2 <= end_2)
{
    if (source[start_1] > source[start_2])
        destination[dest++] = source[start_2++];
    else
        destination[dest++] = source[start_1++];
}

if (start_1 > end_1)
{
    for (; start_2 <= end_2; start_2++)
    {
        destination[dest] = source[start_2];
        dest++;
    }
}
else
{
    for (; start_1 <= end_1; start_1++)
    {
        destination[dest] = source[start_1];
        dest++;
    }
}

}

2 个答案:

答案 0 :(得分:2)

一个非常简单的方法来并行化每个步骤分成两个的递归,具有以下结构:

void recursive_function(int threads_to_use)
{
    if(threads_to_use == 1) {
        recursive_function(1);
        recursive_function(1);
    } else {
        int half = threads_to_use / 2;
        thread th(recursive_function, half);
        recursive_function(threads_to_use - half);
        th.join();
    }
}

它不是理想的解决方案,但它是一个不错的解决方案,并且如果两个调用可以同时完成,相对容易实现现有的单线程设计。

如果您的C ++库提供了很好的实现,那么使用std::async进行异步函数调用而不是进行低级别的线程创建可能会更好......但是我使用的是避免& #39; t真的非常有用(要么创建太多线程,要么根本不做多线程),所以我真的不建议学会使用它。

答案 1 :(得分:0)

我想知道有2000万个整数排序,主要的节奏问题是主内存带宽,即使有多个核心,每个都有本地1级和2级缓存也不会有帮助很多,因为合并排序将涉及大量顺序读取或写入主存储器,我认为这是瓶颈。

我还想知道4个内核是否同时进行合并排序会减少顺序读取和写入主内存的百分比,从而减慢进程。

我在2000万(20 * 1024 * 1024)32位整数上运行了自上而下和自下而上的合并排序,我的系统(Intel 2600K,3.4ghz)都需要大约2秒钟。几乎所有的时间都花在了合并运行功能上,这似乎只比问题中的示例稍微好一点,但这里的代码可能会有所帮助。请注意,[]是原始数组,b []是临时数组。

protected function validateRegex($attribute, $value, $parameters)
    {
        $this->requireParameterCount(1, $parameters, 'regex');

        return preg_match($parameters[0], $value); // **ON THIS LINE**
    }