java - 乘法比分支更快

标签 java optimization cpu gpgpu branch-prediction

为了了解 if 语句与选择性乘法的区别,我尝试了下面的代码,发现将结果乘以 0 而不是 failed-if-statement(false),并乘以 1 而不是 passed-if-statement (true),如果只有 3-4 个 double 乘法,if 语句会更慢,而计算总是会更快。

问题:虽然这种乘法在 CPU 上速度更快,但它在 GPU(opencl/cuda)上的执行情况如何?我的投票是绝对加速。单精度乘法的精度损失怎么样?我知道不可能总是 1.00000,相乘就是 0.999999。 可以说我不介意第五位数字的 sp 精度损失。

这更适合整数,但这至少对 float 有意义吗? 如果 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

最佳答案

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

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

按相反顺序: if(){}:0.1154809 秒。 没有 if: 0.115531714 秒。

多次运行产生不同的结果,但 if/no_if block 实际上是相同的。

您需要一个更详细的基准才能得出有意义的结论。使用热身、稳定的随机种子,对大量调用进行平均。

我也可能(几乎)对微观管理 java 代码毫无用处。它仅适用于特定硬件和特定 VM 版本。 如今,VM 代码优化是如此先进,您将无法相信它能做什么。确保执行的代码与您的字节码有很大不同。

关于java - 乘法比分支更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17478770/

相关文章:

java - 如何设置 ImageView 占据屏幕的宽度?

delphi - Delphi 真的比处理静态类更好地处理动态类吗?

c - 内存共享 C - 性能

performance - 慈善机构如何衡量捐赠的 CPU 使用率?

java - 默认情况下启用 AES-NI 内在函数?

java - jdb-无法找到或加载主类 Main

java - Spring Data JPA 之间 findBy/findAllBy 的区别

java - 如果只给出事件点,如何绘制图表?

algorithm - 初始解接近最优的多元函数优化

iphone - 优化 OpenGL ES 应用程序。我应该尽可能避免调用 glVertexPointer 吗?