乘法比分支快

时间:2013-07-04 22:22:55

标签: java optimization cpu gpgpu branch-prediction

为了了解if语句与选择性乘法,我尝试了下面的代码并看到将结果乘以0而不是fail-if-statement(false)并乘以1而不是pass-if-statement (true),if-statement较慢,如果只有3-4次双精度乘法,则计算总是更快。

问题:虽然这个乘法甚至在cpu上更快,但它在GPU上的表现如何(opencl / cuda)?我的投票是绝对加速。单精度乘法的精度损失怎么样?我知道总是不能有1.00000,它是0.999999倍增。 让我们说我不介意sp精度损失在第5位。

这更适合整数,但这对于至少浮点数是否有意义? 如果float / half乘以比double更快/更快的速度,那么这将更快。

结果:

 no if: 0.058515741 seconds
 if(){}: 0.073415743 seconds

任何人都可以重现类似的结果吗? if(){}是第二次测试,所以JIT不能作弊?

代码:

 public static void main(String[] args)
{
       boolean[]ifBool=new boolean[10000000];
       byte[]ifThen=new byte[10000000];
       double []data=new double[10000000];
       double []data1=new double[10000000];
       double []data2=new double[10000000];

       for(int i=0;i<ifThen.length;i++)
       {
          ifThen[i]=(byte)(0.43+Math.random()); //1 =yes result add, 0= no result add 
          ifBool[i]=(ifThen[i]==1?true:false);
          data[i]=Math.random();
          data1[i]=Math.random();
          data2[i]=Math.random();
      }

         long ref=0,end=0;
         ref=System.nanoTime();
         for(int i=0;i<data.length;i++)
         {
                // multiplying by zero means no change in data
                // multiplying by one means a change in data
            double check=(double)ifThen[i]; // some precision error 0.99999 ?
            data2[i]+=(data[i]*data1[i])*check; // double checked to be sure
            data[i]+=(data2[i]*data1[i])*check; // about adding the result
            data1[i]+=(data[i]*data2[i])*check; // or not adding
                                       //(adding the result or adding a zero)

         }
         end=System.nanoTime();
         System.out.println("no if: "+(end-ref)/1000000000.0+" seconds");

         ref=System.nanoTime();
         for(int i=0;i<data.length;i++)
         {
            if(ifBool[i]) // conventional approach, easy to read
            {
               data2[i]+=data[i]*data1[i];
               data[i]+=data2[i]*data1[i];
               data1[i]+=data[i]*data2[i];
            }
         }
         end=System.nanoTime();
         System.out.println("if(){}: "+(end-ref)/1000000000.0+" seconds");
}

CPU是FX8150 @ 4GHz

1 个答案:

答案 0 :(得分:3)

无法重现结果(仅限CPU)。

原始代码: 如果:0.11589088秒。 if(){}:0.115732277秒。

按相反顺序: if(){}:0.1154809秒。 不,如果:0.115531714秒。

多次运行会产生不同的结果,但是if / no_if块实际上是奇偶校验。

您需要更精细的基准才能得出有些有意义的结论。使用热身,稳定的随机种子,平均很多电话。

我也可能(几乎)无法对微码管理java代码。它仅适用于特定硬件和特定VM版本。 如今,VM代码优化非常先进,你不会相信它能做什么。确保执行的代码与字节码非常不同。