【问题标题】:Parallel Merge Sort with threads /much/ slower than Seq. Merge Sort. Help并行合并排序与线程 /much/ 比 Seq 慢。合并排序。帮助
【发布时间】:2011-09-01 01:59:56
【问题描述】:

http://pastebin.com/YMS4ehRj

^ 这是我的并行归并排序的实现。基本上我所做的是,对于每个拆分,前半部分由线程处理,而后半部分是顺序的(即)说我们有一个由 9 个元素组成的数组,[0..4] 由线程 1 处理,[0 ..1] 由线程 2 处理,[5..6] 由线程 3 处理(请查看源代码以进行澄清)。

其他一切都保持不变,例如合并。但问题是,这比归并排序慢得多,甚至比普通冒泡排序还要慢!我的意思是一个 25000 个整数的数组。我不确定瓶颈在哪里:是互斥锁吗?是合并吗?

关于如何使这更快的任何想法?

【问题讨论】:

  • 对于 stackoverflow 问题,您不应该使用在一天内过期的 pastebin - 它会阻止其他人学习如何在下周解决您的问题(或明天回答您的问题)。
  • 你根本不应该使用 pastebins。
  • 不要通过并行执行相同的位来实现递归样式的合并排序。当子列表下降到 1000 长时,线程通信的开销开始接近合并所花费的时间,所以只需进行快速排序,(或其他任何 - 刚刚看到的帖子 - 同一点)。另外,正如其他人所说,只需将您的合并排队到 [no.核心]线程,或其他一些线程池实现。您可以将合并与回调同步。如果这样做,4/8 核处理器上的“平铺合并排序”将对 1000000 个整数进行排序,比单线程快速排序快六倍。

标签: c pthreads parallel-processing mutex mergesort


【解决方案1】:

您正在创建大量线程,然后每个线程只做很少的工作。要对 25000 个 int 进行排序,您需要创建大约 12500 个线程来生成其他线程并合并它们的结果,以及大约 12500 个线程,每个线程只对 两个 int 进行排序。

创建所有这些线程的开销远远超过了并行处理带来的收益。

为避免这种情况,请确保每个线程都有合理数量的工作要做。例如,如果一个线程发现它只需要对

【讨论】:

    【解决方案2】:

    鉴于系统上的内核数量有限,为什么要创建比内核更多的线程?

    此外,还不清楚为什么您需要一个互斥锁。据我通过快速扫描得知,该程序不需要在本地函数之外共享线程[lthreadcnt]。只需使用一个局部变量,你就应该是金子了。

    【讨论】:

    • 好点。我被这种盒装思维所吸引,因为我已经为此工作了大约 5 个小时。 O.o 而且您确实提出了创建大量线程(〜12500)的观点。那么串行拆分但并行合并会更快吗?
    • 好吧,您可以使用递归限制进行并行拆分(对于 2 和 4 核很好,对于 6 或 8 核不太好),但串行拆分可能会更有效。您也没有进行任何 I/O,因此大量线程不会提高效率。这可能远远超出您想要去的地方,但是如果您可以在缓存行边界上拆分阵列,那么您也可能会在那里获得性能优势,因为争用成本很高。不过,由于查看大量数据的线程较少,这一点就不那么重要了。
    【解决方案3】:

    你的并行度太细了,有太多线程在做一些小工作。您可以定义一个阈值,以便对大小小于阈值的数组进行顺序排序。请注意生成的线程数,一个很好的迹象是线程数通常不会比内核数大多少。

    因为您的大部分计算都在 merge 函数中,所以另一个建议是使用 分治合并 而不是简单的合并。优点有两个:运行时间更短,并且很容易产生线程来运行并行合并。您可以在这里了解如何实现并行合并:http://drdobbs.com/high-performance-computing/229204454。他们还有一篇关于并行合并排序的文章,可能对您有所帮助:http://drdobbs.com/high-performance-computing/229400239

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-15
      • 2021-06-06
      • 2010-10-04
      • 1970-01-01
      • 2021-12-09
      • 2020-03-25
      • 1970-01-01
      • 2018-03-08
      相关资源
      最近更新 更多