掌桥专利:专业的专利平台
掌桥专利
首页

技术领域

本发明涉及高性能计算与算法技术领域,具体涉及一种面向GPU和DCU架构的Flash Sort算法优化方法。

背景技术

在计算机科学与数学中,排序算法可以将一组数据按照特定的排序方式进行排列,常用的排序算法有冒泡排序、插入排序、归并排序、奇偶排序等等。

图形处理器(GPU,Graphics Processing Unit)和深度处理器(DCU,DeepComputing Unit)可以提供强大的并行计算能力和巨大的数据吞吐量,在处理大规模数值计算问题方面表现优异,为高性能计算系统提供了坚实的计算平台。基于GPU和DCU的并行计算能力,算法可以同时对多个数据进行排序,极大的提高排序算法的运行速度。

Flash sort算法在桶排序的基础上加入对数据分布的猜测,减少了桶的用量。但是现有的Flash sort算法没有很好的在GPU和DCU架构上实现优化,资源占用率低,没有充分发挥GPU和DCU加速器的性能,鉴于此,本发明提出了一种面向GPU和DCU架构的FlashSort算法优化方法。

本发明提供了一种Flash sort算法优化方法,将Flash sort算法在GPU和DCU架构上实现并优化,充分利用了GPU、DCU高度并行的优点,提高了Flash sort排序算法的运行速度。

发明内容

本发明的目的在于解决现有Flash sort算法所存在的资源占用率低,总体性能不高的问题,将Flash sort算法在GPU和DCU架构上实现并优化,充分利用GPU、DCU高度并行的优点,提高Flash sort排序算法的运行速度。

为了实现上述目的,本发明采用了如下技术方案:

一种面向GPU和DCU架构的Flash Sort算法优化方法,包括如下步骤:

S1、初始化:根据数组A的大小分别采用device/block/wavefront不同级别的计算,并对参数进行设定,所述参数包括每个线程处理的元素个数以及桶的数量;

S2、计算桶id:每个线程处理多个元素,计算每个元素所属的桶id,并计算每个元素在桶内的编号,储存至LDS(共享内存)中;同时计算每个桶内元素的数量,并存储到数组bucket_size中;

S3、计算前缀和:计算数组bucket_size的前缀和,并根据桶的大小重新划分存储空间,确定每个桶在数组中的起始位置;

S4、将数组元素放入桶内:将数组内的元素重新写入存储空间中,并按照S3中所划分的存储空间对应放入指定的桶空间中;

S5、桶内排序:将线程划分为若干个线程组,每个线程组处理一个桶内排序,每个线程计算桶内元素在桶内的位置,并将其存储到线程的临时数组中;将桶内位置与桶的起始位置相加,得到元素在数组中的位置;

S6、写回最终结果:在所有元素都计算好自身的位置后,每个线程将存储在临时数组的结果重新写回存储空间中。

优选地,所述S1具体包括以下内容:在device级别上,多个block共同处理数组A;在block级别上,一个block处理数组A;在wavefront级别上,一个wavefront处理数组A;根据数组内的元素数量设定桶的个数,并在LDS上开辟固定大小的空间用以存储数组元素。

与现有技术相比,本发明提供了一种面向GPU和DCU架构的Flash Sort算法优化方法,具备以下有益效果:

本发明可以在不同级别上(device/block/wavefront)处理数组A(数组A为待排序数组),根据待排序数组内的元素数值范围设定桶的数量,并按照桶内的元素数量对数组的存储地址重新进行划分,将数组内的元素存储到对应的桶中。将线程划分为若干线程组,每个线程组共同完成一个桶内的元素的排序,每个线程负责桶内多个元素的排序,并预先在LDS上分配存储空间,更具体的:

(1)本发明有效利用了GPU、DCU的并行计算能力:面向GPU、DCU架构实现优化flashsort排序算法,在计算中所有线程共同参与计算,并按照数据量给每个线程平均分配数据,在最差情况下也只会有一个轮次的部分线程处于空闲状态,提高了计算资源的利用率,可以有效提高Flash sort排序算法的运行效率。

(2)本发明能够进行自适应参数设置:根据待排序数组A的元素个数和数值范围自适应调整排序算法的各项参数,加快数组的排序速度,提高运行效率。

(3)本发明有效利用了LDS共享内存:提高数据访问效率,减少线程间通信,将数据放入桶中时在满足并行的情况下无需额外开辟LDS空间,没有大规模的数据拷贝操作,只需重复利用已分配的空间。提高了Flash sort排序算法的运行效率。

附图说明

图1为本发明提出的一种面向GPU和DCU架构的Flash Sort算法优化方法的方法流程图;

图2为本发明所提出的一种面向GPU和DCU架构的Flash Sort算法优化方法的逻辑示意图。

具体实施方式

下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。

请参阅图1,本发明提出一种面向GPU和DCU架构的Flash Sort算法优化方法,具体包括以下内容:

在排序之前首先根据数组A的大小分别采用device/block/wavefront不同级别的计算,并对参数进行设定,包括每个线程处理的元素个数,桶的数量等。在device级别上,多个block共同处理数组A,在block级别上,一个block处理数组A,在wavefront级别上,一个wavefront处理数组A。每个thread计算多个元素所属的桶id,并通过原子加操作获取元素在桶内的位置和桶内的元素总数。对各个桶的元素数量进行前缀和操作,得到每个桶在数组中的起始索引和末端索引,确定每个桶在数组中占据的位置。将数组中的元素按照桶id的位置重新写入数组中,每个元素存储到对应桶所占据的数组位置中。将线程划分为若干个线程组,每个线程组处理一个桶,对桶内数据进行排序操作,每个线程计算多个元素的桶内排序索引,与桶的起始索引相加得到元素在数组中的索引。在完成索引计算后,将元素重新写回到数组中。

请参阅图2,结合图2对数组A的排序操作进行说明:

假定数组长度为9,桶数量为3。线程首先计算每个元素所属的桶id。以第一个元素为例子,其元素值为1,则

实施例1:

以数组A为例(A=a

Device级别:

(1)初始化:在数组A长度较大的情况下,多个block共同处理A的排序,每个block单独处理桶内排序,每个线程处理多个元素。桶bucket的个数定义为bucket_num。将数组A存储在显存中。

(2)计算桶id:遍历数组A,获取数组A的最大最小值,每个block遍历数组A的一部分,将最大最小值存储在显存中。在所有block计算结束后,由单个block读取遍历每个block的结果,得到数组A的最大最小值。每个block内部的thread计算对应元素所属的桶编号bucket_id,

(3)计算前缀和。将每个block的block_bucket_size按列求前缀和,由单个block读取每个block的计算结果block_bucket_size,合并为scan_block_bucket_size。scan_block_bucket_size数组的大小为[block_num,block_bucket_size],其第i行为第i号block的计算结果。每个block对scan_block_bucket_size的一列求前缀和。在block计算前缀和时共进行j轮计算,j=[log

(4)将每个block内的数据重新写入原数组中。block中每个thread处理N个元素,将N个元素和其桶内编号拷贝到本地的临时数组中,再将元素根据桶编号和桶内编号放入指定的桶内,覆盖原有的数据。

(5)桶内排序。一个block处理一个桶的内部排序,每个线程每次处理单个元素,比较单个元素与桶内其他元素的大小,得到元素在桶内的索引。根据globel_bucket_size将桶内索引与桶的起始索引相加,得到元素在数组中的位置。每个线程将处理的元素和数组位置记录在临时数组中。

(6)写回最终结果。在所有线程都结束计算后,根据上一步计算的数组位置,每个线程将存储在临时数组的元素重新写数组中。

Block级别:

(1)初始化:一个block处理数组A,定义每个线程处理N个元素,并定义桶bucket的个数bucket_num。创建LDS数组用于存储数组A。创建LDS数组count用于存储数组A排序后的元素顺序。

(2)计算桶id:block内部的线程共同处理数组A,遍历数组A,每个线程读取数组A的多个数据并进行比较,获取数组A的最大最小值,将最大最小值存储在共享内存中。block内部的thread同时计算数组内元素所属的桶编号

(3)计算前缀和:对bucket_size数组进行前缀和操作,在block计算前缀和时共进行j轮计算,j=[log

(4)将数组A内的数据重新写入原数组中:block中每个thread处理N个元素,将N个元素和桶内编号拷贝到本地的临时数组中,再将元素放入指定的桶内,覆盖原有的数据。

(5)桶内排序:将block内部的线程划分为若干线程组,每组包含2的整数次幂个thread,每一个线程组称为一个vector。每个vector单独处理一个桶的内部排序,每个线程每次处理单个元素,比较单个元素与桶内其他元素的大小,得到元素在桶内的索引。根据bucket_size将桶内索引与桶的起始索引相加,得到元素在数组中的位置。每个线程将元素和数组位置记录在临时数组中。

(6)写回最终结果:在所有线程都结束计算后,根据上一步计算的数组位置,每个线程将存储在临时数组的元素重新写回数组中。

Wavefront级别:

(1)初始化:在数组长度较小,有多个数组需要排序的情况下,定义一个wavefront处理数组A,每个线程处理N个元素,并定义桶bucket的个数bucket_num。创建LDS数组用于存储数组A。创建LDS数组count用于存储数组A排序后的元素顺序。

(2)计算桶id:wavefront内部的线程共同处理线程A,遍历数组A,每个线程读取数组A的多个数据并进行比较,获取数组A的最大最小值,将最大最小值存储在共享内存中。wavefront内部的thread同时计算数组内元素所属的桶编号bucket_id,

(3)计算前缀和:对bucket_size数组进行前缀和操作,在wavefront计算前缀和时共进行j轮计算,j=[log

(4)将数组A内的数据重新写入原数组中:wavefront中每个thread处理N个元素,将N个元素和桶内编号拷贝到本地的临时数组中,再将元素放入指定的桶内,覆盖原有的数据。

(5)桶内排序:将wavefront内部的线程划分为若干组,每组包含2的整数次幂个thread,每一个线程组称为一个vector。每个vector单独处理一个桶的内部排序,每个线程每次处理单个元素,比较单个元素与桶内其他元素的大小,得到元素在桶内的索引。根据bucket_size将桶内索引与桶的起始索引相加,得到元素在数组中的位置。每个线程将元素和数组位置记录在临时数组中。

(6)写回最终结果:在所有线程都结束计算后,根据上一步计算的数组位置,每个线程将存储在临时数组的元素重新写回数组中。

以上所述,仅为本发明较佳的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,根据本发明的技术方案及其发明构思加以等同替换或改变,都应涵盖在本发明的保护范围之内。

技术分类

06120116226481