快速,小面积和低延迟的部分排序算法

时间:2012-11-09 10:28:26

标签: algorithm sorting vhdl verilog fpga

我正在寻找一种快速方法来对81个数字进行部分排序 - 理想情况下,我希望提取最低的16个值(16这个值不是绝对正确的顺序)。

目标是FPGA中的专用硬件 - 所以这有点复杂,因为我希望最终实现的区域尽可能小。我查看并实现了奇偶合并排序算法,但我理想地寻找可能对我的需求更有效的任何东西(交易算法实现大小为部分排序给出最低16,不一定按顺序而不是a完全排序)

非常欢迎任何建议

非常感谢

5 个答案:

答案 0 :(得分:8)

这可以在O(nlog_k)时间内完成,在你的情况下,n = 81和k = 16.当处理大量元素而不是O(nlog_n)时,这非常有效。

算法如下:

  1. Init max heap data data structure。这个堆将包含你的前16个。这个堆的大小不会超过16,它有插入和删除的log(k)
  2. 遍历n个数字列表。每个n:
    • 如果堆少于16个元素,只需添加它
    • 如果堆有16个元素,则将n与堆中的max进行比较(如果大于最大值则跳过,如果小于最大值,则删除max并添加n。)< / LI>
  3. 这种方式在每次迭代时都会跟踪当前处理过的部分列表中最小的k个数字。

答案 1 :(得分:2)

这听起来像某种信号处理内核。如果不知道设计中的确切数据流,很难帮助解决这个问题。任何涉及排序的算法都有地址解码成本,因为您需要能够写入和读取81个元素的内存。如果这些数据在存储器中,则已经支付了这笔费用,但是如果它在不同的寄存器中,那么写入它们会带来面积成本。

假设数据在内存中,您可以使用冒泡排序并获取底部16个值。下面的代码假定一个双端口存储器,但它可以通过在每个时钟周期交替读写来使用单个端口,使用临时寄存器来存储写入值和写入索引。在内存中只有81个元素,这可能没有更大的区域效率。 或者,源存储器可以实现为两个单端口存储器,其中一个具有奇数索引而另一个具有偶数索引。

// Not working code 
reg [15:0] inData [80:0]; // Must be two-port
reg [3:0]  iterCount = 0;
reg [6:0]  index = 0;
reg sorting;

always @(posedge clk)
  begin
  // Some condition to control execution
  if(sorting)
    begin

    if(index == 80)
      begin 

      // Stop after 16 iterations
      if(iterCount == 15)
        begin
        sorting <= 0;
        iterCount <= 0;
        end
      else
        begin
        iterCount <= iterCount+1;
        index <= 0;
        end
      end 
    else
      begin
      // If this is smaller than next item
      if(inData[index] < inData[index+1])
        begin
        // Swap with next item
        inData[index+1] <= inData[index];
        inData[index]   <= inData[index+1];
        end
      index <= index + 1;
      end
    end
  end

编辑:如果您受到延迟限制,只允许一个时钟域并且必须进行管道传输,那么问题仅限于选择排序网络并将其映射到管道。您无法使用资源共享,因此根据您的分拣网络,区域是固定的。

  • 为N = 81(不容易)
  • 选择排序网络(Bitonic,Pairwise等)
  • 构建表示分拣网络的定向数据流图
  • 删除除输出66-81
  • 所需的节点以外的所有节点
  • 确定一个比较节点的延迟L
  • 使用ALAP调度来为每个时钟分配M个节点,其中M * L <1。的1 / f
  • 如果计划成功,则以HDL编码

答案 2 :(得分:1)

如果您正在寻找通用算法,那么您可以使用Quicksort版本。 Quicksort对pivot元素周围的值进行排序。您选择一个轴并对阵列进行排序。然后你得到x值&lt;枢轴和(n-x-1)个较大的。根据x,您可以选择一个阵列来继续处理。如果x> 16,那么您知道您要查找的数字都在x数组中,您可以继续对其进行排序。如果没有,那么你知道x最低,现在可以递归地在另一个数组中寻找16-x其他。

生成的快速排序数组未完全排序,您只知道它们比您的数据透镜更小或更大。 wikipediaa paper上的一些信息。

答案 3 :(得分:0)

也许修改中位数选择是一种选择?否则,你只需寻找最少16次就可行吗?

答案 4 :(得分:0)

首先设置一个包含16个值的数组。并使用类似选择的东西:

  1. 您认为第一个值是数组中的最小值。
  2. 比较第一个元素的值,第二个,直到找到一个低于它的数字。
  3. 将其作为新的最小值,并将其与下一个数字进行比较,直至找到低于它的数字。
  4. 如果您完成了数组,那么您拥有的数字就是最小数量,将其保存在数组中并将其从源数组中排除,然后重新开始直到填满解决方案数组的16个位置。