【问题标题】:Fastest Multithreading Sorting Method最快的多线程排序方法
【发布时间】:2017-11-16 23:18:09
【问题描述】:

目前,我正在创建一个多线程排序器,它读取一堆 CSV 文件并输出一个包含 CSV 文件中所有数据的大型排序 CSV 文件。现在,我计划使用 mergesort 对它们各自线程中的每个 CSV 进行排序,然后在来自线程的所有数据连接在一起时最后一次对其进行排序。我只是好奇是否只使用合并排序会被认为是“快速”。在线程将已排序的数据连接在一起后,数据在其各个部分中排序,但总体而言,它仍然是未排序的。

【问题讨论】:

标签: c multithreading sorting time mergesort


【解决方案1】:

由于合并函数中的循环相对紧凑,我认为合并排序会受到内存限制,直到我进行了多线程自下而上合并排序。使用 4 个线程,它的速度大约是单线程合并排序的 3 倍。在这个例子中,数组被分成 4 个部分,每个部分都归并排序,然后线程 0 合并四分之一数组 0 和 1,线程 2 合并四分之一数组 2 和 3,然后线程 0 合并两个半数组。 /p>

https://codereview.stackexchange.com/questions/148025/multithreaded-bottom-up-merge-sort

gnu 排序是一种文本文件排序,它在用于创建初始临时文件的第一遍中对指针数组进行多线程合并排序(假设原始文件大于可用内存)。在第一次通过后,它会对临时文件进行单线程 16 路合并,因为瓶颈是磁盘 I/O 速度,而不是处理器速度。

【讨论】:

  • 这听起来是个不错的解决方案。我正计划连接单独排序的数组并再次合并排序,但这只是在浪费时间,因为它们基本上处于合并排序的最后一步,即合并部分。现在我只是在考虑是否应该使用链表或仅使用另一个数组来将文件的所有单个结构数组保存在一起。
  • @codemonkey - 您可以使用指向结构的指针数组,而不是使用链表。
【解决方案2】:

您的数据有多大?排序是O(n log n),本质上不可并行化的最终合并步骤当然是O(n),所以除非log n 非常庞大,或者与移动数据的成本相比,比较成本不成比例地大,否则非常多线程排序收效甚微。

如果您仍然想尝试它,那么您的方法有什么问题是对连接列表进行最终合并排序。这基本上与重新进行整个排序的速度相同。相反,您希望使用单个合并操作而不是整个合并排序来合并每对线程的输出。重复此操作,将每次排序列表的数量减半,直到最后一步仅合并 2 个列表。您可以通过设置线程之间的层次关系将这项工作分解为线程,其中,当层次结构中的两个“兄弟”线程完成其工作时,一个退出,另一个在层次结构中“向上移动”并开始合并其兄弟的输出.

【讨论】:

  • 我不同意您第一段中的论点。合并排序中的每次传递都需要大致相同的时间(因为早期的传递必须进行更多的合并,而后面的传递必须在更大的列表上进行合并),所以即使 log n 相对较低——比如说,大约 25 (意味着大约 3400 万个项目)- 并行化早期通道会对总时间产生相当大的影响。
  • 每个文件有 28 列和大约 5000 行。文件数量范围为 1 - 1024。
  • 您可以在比启动线程所需的时间更短的时间内对 50000 行(10 倍多)进行排序。除非您有数十亿行,否则多线程排序甚至没有任何意义。
  • 5,000 * 1024 大约是可以存在的最大行数,即 5,120,000 行。
  • 哦,我误读为总共 5000 行。尽管如此,即使是 5M 行也足够小,不太可能有帮助。日志大约是 22。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 2014-08-08
  • 2011-02-22
  • 1970-01-01
  • 2021-03-11
相关资源
最近更新 更多