确定非零最小值的最快方法

时间:2012-01-15 03:33:04

标签: c++ algorithm minimum

拥有一个例如4个整数的数组,如何以最快的方式确定它的非零最小值?

5 个答案:

答案 0 :(得分:8)

除非你保持最小值,因为元素被添加到数组中,或者你保持数组的排序顺序 - 我没有看到其他解决方案,只是迭代每个成员来确定最小值。

没有“快速”的方法来测试每个成员。

一般情况下,我建议不要优化某些东西,除非事实证明它很慢。你的程序的旧规则花费90%的时间在10%的代码中通常是正确的。那么程序员99.99%的规则可能会优化不超过10%的代码。

描述您的代码 - 描述您的代码 - 描述您的代码

答案 1 :(得分:6)

这个问题有一个平行的解决方案,但它可能不值得努力。

首先,我们在数组 a

上定义一个操作xchg(m, n)
xchg(m, n) => ((a[m] > a[n] && a[n] != 0) || a[m] == 0) ? swap(a[m],a[n])

如果两个元素'm'和'n'都包含非零值,则按升序排序两个元素'm'和'n',如果'm'元素中的值为零,则交换它们。

接下来,我们执行一组五个这样的操作如下:

xchg(0,2) xchg(1,3)
xchg(0,1) xchg(2,3)
xchg(1,2)

成对的xchg操作可以并行执行,与严格的顺序执行相比,时间成本降低了40%。当我们完成时,数组中的任何非零元素将按升序排序。最小值元素将在[0]中。如果该值为零,则数组中没有非零值。

此解决方案利用了排序网络(http://en.wikipedia.org/wiki/Sorting_network)提供的固有并行性,但是对4个元素的顺序扫描也使用了不超过三个比较操作,并且至关重要的是平均需要一半的存储写入:

顺序扫描

int v = a[0]
for (n = 1; n < 4; n++) {
   if ((a[n] < v && a[n] != 0 ) || v == 0) v = a[n]
} 

答案 2 :(得分:4)

如果我们考虑微优化,那么在现代无序处理器上计算min(min(a,b),min(c,d))而不是min(min(min(a,b),c),d)可能会更快,因为顺序依赖性较小:前者如果处理器具有足够的可用执行单元,则可以并行独立地计算min(a,b)min(c,d)。这假设处理器具有条件移动指令,因此计算min不需要分支。

答案 3 :(得分:3)

取决于输入。如果数组没有排序,那么你必须遍历整个数组。如果数组已经排序,那么你只需要循环直到找到一些不为零的东西 - 它要短得多。

答案 4 :(得分:1)

最快的编码方式是std::min({a,b,c,d})

更严重的说明:如果你的应用程序是瓶颈,比如采用最少的大量值,那么更好的解决方案可能是找到一种方法将最小查找任务分成几部分并发送到GPU(或者许多线程),然后可以同时操作许多最小发现计算。

并行性可能比尝试在汇编中编写最小函数更有帮助。