排序算法的简要调研

排序算法的代价

排序算法的时间代价主要由排序的时间复杂度决定。目前常见的排序算法根据其时间复杂度可以分为3类:O(n2)O(n^2)O(nlogn)O(nlogn)O(n)O(n)。其中O(n2)O(n^2)复杂度的算法随着排序规模增大运行时间难以容忍,而O(n)O(n)复杂度的算法通常对序列的排序元素类型有一定限制,因此最常使用的排序算法复杂度为O(nlogn)O(nlogn)。任何一个与排序元素类型无关的排序算法,其时间复杂度下界为O(nlogn)O(nlogn)

如果希望排序算法和排序元素类型无关,排序只能通过值比较的方式完成。如果一个序列存在一个偏序关系\le(也即可值可比较),这个序列必定可以用基于值比较的排序算法进行排序。可以证明,完成排序所需要的值比较次数下界为O(nlogn)O(nlogn)[1]。因此任何一个与排序元素类型无关的排序算法,其时间复杂度下界为O(nlogn)O(nlogn)

目前较多排序算法的时间复杂度均为O(nlogn)O(nlogn),但是它们面对不同规模的负载,运行在不同的硬件环境下时却各有优劣。这是因为排序算法的代价还与Cache/TLB 缺失、branch指令总数以及指令级并行性有关

常见排序算法及其应用场景

根据期望时间复杂度划分,目前的排序算法主要有以下几种:

  • O(n2)O(n^2):冒泡排序,插入排序,选择排序,cyclesortcyclesort
  • O(nlog2n)O(nlog^2n):希尔排序,原地归并排序
  • O(nlogn)O(nlogn):归并排序,快速排序,推排序,二叉树排序,冒泡排序的变种combsortcombsort,插入排序的变种图书馆排序
  • O(n)O(n):基数排序,计数排序
  1. 当数据规模较小时,适合使用插入排序、combsortcombsort和选择排序。如果数据规模较小且两个数据元素比较代价低,交换代价高,例如型如<key,payload>的数据,其中payload长度远大于key,适合采用选择排序。
  2. 当数据规模较大时,适合采用快速排序,堆排序和归并排序。如果排序有稳定性需求时,适合采用归并排序。
  3. 当数据接近有序时,可采用插入排序或者冒泡排序。
  4. 当数据为整数时,适合采用基数排序。特别地,若整数数据值较小且重复值较多时,可采用计数排序。
  5. 当底层内存设备读写代价不对称时例如PCM内存时,适合采用选择排序和cyclesortcyclesort,因为两者的总写次数为O(n)O(n).
  6. 当数据规模远大于可用内存空间时,采用外部多路归并。

排序算法的优化方向

目前的排序算法的优化研究主要有四个方向:指令级并行SIMD,线程级并行,新型内存技术,AI4Sort。

指令级并行

单指令多数据流(SIMD)是一种采用一个控制器来控制多个处理器,同时对一组数据(又称“数据向量”)中的每一个分别执行相同的操作从而实现空间上的并行性的技术。排序网络(Sorting Network)是由多个比较器组织成的网络结构,有n个输入端口和输出端口,可将n个无序数据输入转化为对应的有序输出。排序网络并行地工作,可大大提高排序地速度。

在这里插入图片描述

利用SIMD指令实现的排序网络,可对位于向量寄存器中的无序数据并行地排序,且向量排序过程没有分支跳转指令,这大大减少总排序过程的指令代价[2-3]。但是利用SIMD技术进行排序规模受限于向量寄存器的长度,因此SIMD实现的排序网络只可作为building block,它生成多个有序的小向量,然后外层将这多个有序向量进行归并。

quicksort并不适合利用SIMD来优化,因为quicksort的划分出来的子块并不均匀。对于归并排序算法而言,基本所有的子块大小都相等,因此当子块大小划分达到向量长度阈值时,可以采用SIMD来加速对子块的排序。

进程级并行:

多处理器并行排序算法主要分为两大类:merge-based 和 splitter-based算法。其中merge-based算法代表为bitonic sort,splitter-based算法代表有sample-sort和histogram-sort。此外还有radix-sort的并行版本。

merge-based的算法和splitter-based的算法均需要将排序工作量划分给多个处理器,从而成倍地减少总时间代价。两种算法地差别在于处理器将局部有序数据得到最终全序数据的方式:

  • merge-based算法在每个处理器执行局部数据的排序之后,采用并行merge的方式得到最终的有序数据。merge阶段中通信次数较多,通常为one-to-one通信模式;
  • splitter-based算法完成局部数据排序后,则尝试抽取数据中的p-1个数据作为splitter,根据它将每个处理器局部数据划分成p块,然后处理器执行一次all-to-all通信将对应块发送给对应处理器。此后处理器之间数据有序,每个处理器将接受到的p个数据块merge后得到最终结果。

在松耦合的处理器结点网络中,网络通信代价往往是系统的瓶颈所在,在这种系统下需要尽量减少数据传输量和传输次数,以及结点同步操作。splitter-based算法具有通信数据传输少,且同步代价低的优点,因此常常成为优先考虑的优化对象[4]。此外,很多研究均希望提高划分元素划分的均匀性,从而提高算法的扩展性和适应性。

新型内存:

非易失性内存(NVM)引入之后,传统的内存排序算法获得了新的研究契机。NVM技术存在诸多与DRAM大不相同的特性,其中影响排序性能的NVM特性主要为读写延迟稍高,读写代价不对称性和持久性。针对NVM内存排序研究可根据其考虑的内存架构划分:DRAM和NVM上下级架构,DRAM和NVM混合架构,纯NVM内存架构。

  • DRAM和NVM上下级架构下,内存排序的优化点在于减少DRAM与NVM之间的通信代价[5,6]。这类似传统外部排序需要减少DRAM和HDD/SSD的I/O代价,但不同点在于I/O粒度不再为page,同时I代价可能会低于O代价。外部多路归并排序十分适合这种场景,因为多路归并能显著减少总I/O次数,且能够适应DRAM空间较少的环境。文献[7]从形式化角度考虑了面对读写不对称架构下,多路归并排序通过以读换写的方式,减少归并阶段的趟数,从而减少对下层介质的总I/O次数。文献[5]的研究则同样考虑多路归并排序算法,并利用一些相关技术减少多路归并过程中的数据写回。
  • 在混合DRAM和NVM内存架构下,内存排序优化点在于如何将内存排序的读写集中在延迟更低的DRAM内存空间上去。文献[6]认为,多路归并排序是最适合混合内存架构下的排序算法。作者认为只需要让排序算法将混合内存空间当成上下层架构,充分减少DRAM和NVM之间的数据移动代价即load store次数即可。
  • 针对纯NVM内存架构的排序算法,其优化点会集中在如何在只引入O(n)O(n)的写的情况下,将算法时间复杂度降低O(nlogn)O(nlogn)及以下(我们知道,选择排序和cycle排序的写代价仅为O(n)O(n),但是其总时间代价太差)。文献[8]研究了近似存储(Approximate computing,近似存储是牺牲写的精确性以降低写延迟提高写性能的存储技术,PCM就是这样的一种持久性近似存储)内存技术下不同排序算法性能。为了保证最终排序的正确性,在近似存储上的排序结果需要经过一个精炼阶段,这将与机器学习技术引入排序算法类似。
AI4Sort:

众所周知,机器学习技术大都是基于统计学和概率论的学习算法,因此并不能保证结果的绝对(100%)精确。而稳定的排序算法针对每个输入只有唯一的输出,这是一个精确地排序过程。应用机器学习技术提升排序算法性能,势必在需要排序最后引入一个精炼阶段。文献[9,10]提出了利用机器学习技术,从历史的排序数据中学习得出一个在无序数列的数据到其最终有序位置的映射,根据这个模型我们可以在线性时间内将无序数据排序成一个大致有序的数列,最后利用精炼步骤将这个大致有序的数据排序。由于机器学习模型排序数据大致有序,最终精炼步骤的时间代价可以大大缩减,在实际应用中,可能达到总体上线性的排序时延。

参考文献:

[1]. 基于比较的排序算法复杂度下限, https://www.zhihu.com/question/24516934/answer/28076722

[2]. Hiroshi Inoue, Kenjiro Taura: SIMD- and Cache-Friendly Algorithm for Sorting an Array of Structures. PVLDB 8(11): 1274-1285 (2015)

[3]. Michael Codish, Luís Cruz-Filipe, Markus Nebel, Peter Schneider-Kamp: Optimizing sorting algorithms by using sorting networks. Formal Asp. Comput. 29(3): 559-579 (2017)

[4]. Edgar Solomonik, Laxmikant V. Kalé: Highly scalable parallel sorting. IPDPS 2010: 1-12

[5]. Stratis Viglas: Write-limited sorts and joins for persistent memory. PVLDB 7(5): 413-424 (2014)

[6]. Mohammed Bey Ahmed Khernache, Arezki Laga, Jalil Boukhobza: MONTRES-NVM: An External Sorting Algorithm for Hybrid Memory. NVMSA 2018: 49-54

[7]. Guy E. Blelloch, Jeremy T. Fineman, Phillip B. Gibbons, Yan Gu, Julian Shun: Sorting with Asymmetric Read and Write Costs. SPAA 2015: 1-12

[8]. Shuang Chen, Shunning Jiang, Bingsheng He, Xueyan Tang: A Study of Sorting Algorithms on Approximate Memory. SIGMOD Conference 2016: 647-662

[9]. Zhu, Xiao-ke, Taining Cheng, Qi Zhang, Ling Liu, Jing He, Shaowen Yao and Wei Zhou. NN-sort: Neural Network based Data Distribution-aware Sorting. (2019).

[10]. The case for a learned sorting algorithm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章