【问题标题】:Parallel mergesort with parallel merge并行合并排序与并行合并
【发布时间】:2017-12-13 15:47:06
【问题描述】:

如何使用并行合并进行并行合并排序?我在互联网上没有找到任何伪代码,我只知道如何通过为左右生成两个线程来并行化合并排序的第一部分,但是如何并行化合并?这是我需要并行化的合并代码。

public static int[] merge(int[] left, int[] right, int[] array) {
    int i = 0;
    int j = 0;
    int k = 0;
    while (i < left.length && j < right.length) {
        if (left[i] <= right[j]) {
            array[k] = left[i];
            i++;
        }
        else {
            array[k] = right[j];
            j++;
        }
        k++;
    }
    while (i < left.length) {
        array[k] = left[i];
        i++;
        k++;
    }
    while (j < right.length) {
        array[k] = right[j];
        j++;
        k++;
    }
    return array;

【问题讨论】:

    标签: multithreading algorithm sorting parallel-processing mergesort


    【解决方案1】:

    执行此操作的一种方法是将数组拆分为 k 个部分用于 k 个线程,并行执行 k 个合并排序,然后合并 k 个部分。例如,对于 4 个线程,并行完成 4 个合并排序,例如使用线程 0、1、2、3。线程 1 和 3 在合并排序后终止。在线程 2 进行归并排序之后,它等待线程 3 终止,合并来自线程 2 和 3 的已排序部分,然后终止。在线程 0 进行合并排序后,它等待线程 1 终止,合并线程 0 和 1 的部分,等待线程 2 终止,将线程 0 中排序的一半与线程 2 中排序的一半合并。在测试中我编写的程序,我在启动线程之前分配了第二个工作数组。最初的 1/4 数组线程排序以排序后的 1/4 部分返回原始数组,1/4 + 1/4 合并以工作数组中的排序数据结束,最后的 1/2 + 1/2 合并最终回到原始数组中。

    【讨论】:

      【解决方案2】:

      灵感来自this 我已经尝试实现您的代码的并行版本。基本思想是将问题分成几部分,然后在另一项任务中处理每一部分。我没有测试过,可能有错误。

              public static int[] MergePll(int[] left, int[] right)
              {
                  int[] arr = new int[left.Length + right.Length];
                  int maxProcessCount = Environment.ProcessorCount * 8;
                  int leftPiece = Math.Max(1, left.Length / maxProcessCount);
                  int rightPiece = Math.Max(1, right.Length / maxProcessCount);
                  Parallel.For(0, maxProcessCount, (i) =>
                  {
                      int leftStart = leftPiece * i;
                      int leftEnd = Math.Min(left.Length, leftStart + leftPiece);
                      int rightStart = rightPiece * i;
                      int rightEnd = Math.Min(right.Length, rightStart + rightPiece);
                      int start = leftPiece * i + rightPiece * i;
                      _merge(left, right, leftStart, leftEnd, rightStart, rightEnd, arr, start);
                  });
                  return arr;
              }
              private static void _merge(int[] left, int[] right, int leftStart, int leftEnd, int rightStart, int rightEnd, int[] arr, int start)
              {            
                  while (leftStart < leftEnd && rightStart < rightEnd)
                      if (left[leftStart] <= right[rightStart])
                          arr[start++] = left[leftStart++];
                      else
                          arr[start++] = right[rightStart++];
                  while (leftStart < leftEnd)
                      arr[start++] = left[leftStart++];
                  while (rightStart < rightEnd)
                      arr[start++] = right[rightStart++];
              }
      

      编辑:这是不完整的,仅适用于“1,3,5,7”-“2,4,6,8”之类的数据,我会尝试解决它。​​

      【讨论】:

        猜你喜欢
        • 2011-09-01
        • 1970-01-01
        • 2012-01-16
        • 1970-01-01
        • 2012-11-28
        • 1970-01-01
        • 2018-03-08
        • 2016-04-22
        • 2011-04-01
        相关资源
        最近更新 更多