自适应排序算法与排序网络,用于排序32个随机元素的列表

时间:2018-04-26 10:41:00

标签: arrays algorithm sorting optimization sorting-network

如果我们使用顺序机器(不可能进行并行比较),按顺序进行比较,并且我们希望在排序32个随机元素时最大限度地减少处理器时钟周期的数量,我们是否应该使用分类网络或自适应排序算法?

对于n = 32个元素,还没有最佳网络。实际上,如果我们想要最小化CPU时钟周期的数量,最好将32个元素分成4个n = 8的子列表,并在每个子列表上应用最优的排序网络,然后将列表合并在一起?

我们显然在这里使用“平均性能”,因为如果给出已经排序的列表,自适应算法会很幸运。

处理数字我们有以下内容:

对大小为n的列表进行排序:

  • n = 2的最小比较数为1.

  • n = 4的最小比较数为5。

  • n = 8的最小比较数为19。

合并两个大小为n的列表:

  • 合并两个n = 2的列表是2 * n - 1 = 3个比较

  • 合并两个n = 4的列表是2 * n - 1 = 7个比较

  • 合并两个n = 8的列表是2 * n - 1 = 15个比较。

  • 合并两个n = 16的列表是2 * n - 1 = 31个比较。

如果我们将n = 32除以16个n = 2个子列表,则进行比较总数:

  • 排序:1 * 16 = 16
  • 合并:3 * 8 + 7 * 4 + 15 * 2 + 31 * 1 = 113
  • 总计:129

如果我们将n = 32分成8个n = 4个子列表,则总比较次数:

  • 排序:5 * 8 = 40
  • 合并:7 * 4 + 15 * 2 + 31 * 1 = 89
  • 总计:129

如果我们将n = 32分成四个n = 8个子列表,则总比较次数:

  • 排序:19 * 4 = 76
  • 合并:15 * 2 + 31 * 1 = 61
  • 总计:137

现在有人可能认为将n = 32个元素划分为n = 2或n = 4个子列表会更好,因为比较总数较小。但是,mergin要求将数组的部分存储在“不合适的地方”,这可能会抵消较少比较的好处?

我的直觉告诉我,平均而言,非自适应排序网络在总比较方面类似于算法,但排序网络由于开销较少而获胜,我是对的吗?

我试图平均在不到1200个时钟周期内对n = 32个元素进行排序。我正在使用一个简单的 256字* 16位内存和只有四个寄存器工作on a simple sequential machine,因此网络/算法必须简单,快速且不需要大量空间。 ALU仅具有加,减,一位移位,一位旋转,AND和OR功能。内存和ALU操作各占一个时钟周期。

1 个答案:

答案 0 :(得分:1)

堆排序是nlogn。索引计算是微不足道的 - 要比较的项目总是具有n,2n + {1,2}的索引,使得它在您的架构中具有计算效率。

堆排序的主力基本上是例程:

while(true){
    r=(i+1)*2; l=r-1;
    if (*l > * i) { 
       if (*r > *l) swap(i,r);
       else swap(i,l);
    }
    else { 
       if (*r >* i) swap(i,r);
       else break;
    }
 }

交换操作必须作为副作用还将地址i更新为lr。 与教科书解决方案不同,我们不检查子项的地址是否有效,但我们交换空间以加速在数组末尾分配32个零的缓冲区。一旦i不大于任何一个子节点,遍历到堆的底部就会结束。