我试图在Designing Efficient Sorting Algorithms for Manycore GPUs上提到的CUDA上实现合并排序算法。
对于这个,因为在中间级别,它建议分配一个线程块来将两个排序的数组(比如A和B)合并到一个数组。并且想法是为数据分配线程 - 在阵列A上的a_i并使用二进制搜索在B阵列上找到它的位置。如果B上的a_i的位置是j,则a_i在新数组上的位置是(i + j)
但是当我实现这个(或尝试过)时,我发现上面的方法似乎不起作用。例如,如果需要合并的两个数组如下,
和
因此第一个数组上的53(灰色阴影部分)将发现它在第二个数组上的相应位置是11,所以它在最终数组上的位置是(11 + 11 = 22)。同样,第一个阵列上53的蓝色阴影位置是(11 + 12 = 23)。
如果我们取第二个阵列中的53个,其最终位置也是(11 + 11 = 22)。哪个与第一个阵列上的灰色53相冲突。
因此根据我的理解,不能使用简单的二进制搜索算法来合并这两个数组。是否有已知或更简单的方法来解决此冲突?
答案 0 :(得分:1)
在论文中,我读到了:
给定排序的序列A和B,我们想要计算排序的 序列C =合并(A,B)。如果这些序列足够小, 比如说大小不超过t = 256个元素,我们可以合并它们 使用单个T线程块。对于元素ai∈A,我们只需要 计算等级(ai,C),它是元素ai的位置 合并序列C.由于A和B都已排序,我们知道 rank(ai,C)= i + rank(ai,B),其中rank(ai,B)就是 元素bj∈B的计数,其中bj < ai,我们有效地计算 使用二进制搜索。 B的元素显然可以在 同样的方式。
当您在寻找排名(ai,B)时,您必须处理二进制搜索中的重复项。想象B作为BST,等级(ai,B)= j的最大值{bj <= ai} +1应运行良好。
答案 1 :(得分:0)
对不起,我来晚了,但是我只是尝试在FPGA上实现相同的算法。
如果只使用<=比较将A二进制排序为B,而将B排序为A比较,则应该工作。这样可以保证A中的元素在索引中的位置总是比B中的元素低。 B,即使它们相同。
在您的示例中,职位是:
旁注:为索引编制,我建议从0开始计数(为清晰起见,我选择与您相同的计数)。像这样,数组C中的第一个索引是1 +1 = 2