G-Spider 发表于 2010-12-15 23:28:57

10# gxqcn
呵呵,是有点,我测试了一下我的这个:

liangbch 发表于 2010-12-16 01:37:58

对于64bit 整数比较,没有和PMINUD,PMAXUD类似的指令. 我想,只能使用CMOVcc系列指令了。

gxqcn 发表于 2010-12-16 07:46:39

也许,传说中的 AVX 指令可完美解决该问题吧。

liangbch 发表于 2010-12-16 21:00:14

在许多情况下,并不是执行的指令数越多越耗时。程序的运行时间除了和在运行路径中执行的指令数有关,还和分支预测,cache命中率等因素有密切的关。有时这类因素往往占主导地位。今天终于找到一个例子,说明分支预测失败的影响有多大。下面给出两个求数组最大最小值函数。
   在第一个例子中,数组的每一个元素对应2次比较。在每次比较中,两个分支执行的几率并不相同。“if”语句条件为真几率非常小,按照算法导论中的算法,if语句条件为真次数仅为log2(n),n为数组元素的个数。在这种情况下,CPU 的分支预测和取指机构总是预取条件为假的那个分支的指令,预测失败的几率非常低,故CPU的效率很高。
   在第二个例子中,数组的每一个元素对于1.5次比较,执行的指令数比第一个函数少。但是,在平均情况下,第一个比较语句 "if ( pData[ i ] > pData[ i+1 ] )"条件为真的概率为50%,这时CPU的分支预测将不起作用,无论预取那个分支的指令,预测失败的概率总是50%。测试结果显示查找32M个数据,第一个函数需要0.048秒,第二个函数却需要0.098秒,是第一个函数执行时间的2倍多。void getMaxMin1(DWORD *pData,int len,DWORD *min,DWORD *max)
{
    int i;
    *min=~0;
    *max=0;
    for (i=0;i<len;i++)
    {
      if ( pData[ i ] > *max)
            *max=pData[ i ];
      if (pData[ i ]< *min)
            *min=pData[ i ];
    }
}

void getMaxMin2(DWORD *pData,int len,DWORD *min,DWORD *max)
{
    int i;
   
    if (len % 2 ==0 )
    {
      if ( pData > pData )
      {
            *max= pData;
            *min= pData;
      }
      else
      {
            *max= pData;
            *min= pData;
      }
      i=2;
    }
    else
    {
      *max= *min= pData;
      i=1;
    }
   
    for (;i<len;i+=2)
    {
      if ( pData[ i ] > pData[ i+1] )
      {
            if ( pData[ i ]> *max)
            *max=pData[ i ];
            
            if ( pData[ i+1]< *min)
            *min=pData[ i+1];
      }
      else
      {
            if ( pData[ i ] < *min)
            *min=pData[ i ];
            
            if ( pData[ i+1]> *max)
            *max=pData[ i+1];
      }
    }
}

gxqcn 发表于 2010-12-17 07:30:17

请教一下:“CPU 的分支预测”的原理或表现是什么?我一直不太清楚。
它倾向于“为真”还是“为假”?还是依据该处指令先前执行的结果?

mathe 发表于 2010-12-17 09:37:14

根据以前执行的结果,如果以前执行的结果大部分情况跳转,那么就预测跳转.
不过进行预测需要消耗用于预测的寄存器(存放统计数据),而预测寄存器数目有限(比如20个左右).所以不是所有的跳转都会预测,只会预测执行频率高的那些跳转

gxqcn 发表于 2010-12-17 10:09:24

谢谢 mathe 的专业且权威的解答。

gxqcn 发表于 2010-12-17 10:10:57

我在想,分支预测可能对循环的执行有很大好处吧?

G-Spider 发表于 2010-12-17 10:19:37

18# gxqcn
我想,对于循环,如果在循环内(计算指令较多)或循环外把握好数据预取的距离,用数据预取可能会有较大的收益。

gxqcn 发表于 2010-12-17 10:27:34

对数据预取我不太熟,但也说明了cache很重要。
所以有些算法会特意去读取CPU的L1/L2 cache的大小。
页: 1 [2] 3 4
查看完整版本: 求一个数组中元素的最大值和最小值