Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 具有恒定长度的System.arraycopy_Java_Arrays_Microbenchmark_Jmh - Fatal编程技术网

Java 具有恒定长度的System.arraycopy

Java 具有恒定长度的System.arraycopy,java,arrays,microbenchmark,jmh,Java,Arrays,Microbenchmark,Jmh,我在玩弄JMH(),我只是偶然发现了一个奇怪的结果 我正在对制作数组的浅层副本的方法进行基准测试,我可以观察到预期的结果(在数组中循环是个坏主意,#clone(),System#arraycopy()和Arrays#copyOf(),从性能上看,它们之间没有显著差异) 除了当数组的长度被硬编码时,System#arraycopy()会慢四分之一。。。等等,什么?怎么能慢一点呢 有人知道原因是什么吗 结果(吞吐量): #jmh1.11(17天前发布) #虚拟机版本:JDK 1.8.0_05,虚拟机

我在玩弄JMH(),我只是偶然发现了一个奇怪的结果

我正在对制作数组的浅层副本的方法进行基准测试,我可以观察到预期的结果(在数组中循环是个坏主意,
#clone()
System#arraycopy()
Arrays#copyOf()
,从性能上看,它们之间没有显著差异)

除了当数组的长度被硬编码时,
System#arraycopy()
会慢四分之一。。。等等,什么?怎么能慢一点呢

有人知道原因是什么吗

结果(吞吐量):

#jmh1.11(17天前发布)
#虚拟机版本:JDK 1.8.0_05,虚拟机25.5-b02
#VM调用程序:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/bin/Java
#VM选项:-Dfile.encoding=UTF-8-Duser.country=FR-Duser.language=FR-Duser.variant
#预热:20次迭代,每次1s
#测量:20次迭代,每次1s
#超时:每次迭代10分钟
#线程:1个线程,将同步迭代
#基准模式:吞吐量,操作/时间
基准模式Cnt分数误差单位
阵列复制基准。thrpt 20 67100500319±455252537 ops/s的阵列复制
ArrayCopyBenchmark.ArrayCopyof_类thrpt 20 65246374290±976481330 ops/s
ArrayCopyBenchmark.ArrayCopyOf_Class_ConstantSize thrpt 20 65068143162±1597390531 ops/s
ArrayCopyBenchmark.ArrayCopyOf_ConstantSize thrpt 20 64463603462±953946811 ops/s
ArrayCopyBenchmark.克隆thrpt 20 64837239393±834353404 ops/s
阵列COPYBENCHMARK.环路thrpt 20 21070422097±112595764 ops/s
ArrayCopyBenchmark.Loop_ConstantSize thrpt 20 24458867274±181486291 ops/s
ArrayCopyBenchmark.SystemArrayCopy thrpt 20 66688368490±582416954 ops/s
ArrayCopyBenchmark.SystemArrayCopy_ConstantSize thrpt 20 48992312357±298807039 ops/s
基准类:

导入java.util.array;
导入java.util.concurrent.TimeUnit;
导入org.openjdk.jmh.annotations.Benchmark;
导入org.openjdk.jmh.annotations.BenchmarkMode;
导入org.openjdk.jmh.annotations.Mode;
导入org.openjdk.jmh.annotations.OutputTimeUnit;
导入org.openjdk.jmh.annotations.Scope;
导入org.openjdk.jmh.annotations.Setup;
导入org.openjdk.jmh.annotations.State;
@国家(范围、基准)
@基准模式(模式吞吐量)
@输出时间单位(时间单位秒)
公共类ArrayCopyBenchmark{
私有静态最终整数长度=32;
私有对象[]数组;
@设置
在()之前公开无效{
数组=新对象[长度];
for(int i=0;i
像往常一样,通过研究生成的代码可以快速回答此类问题。JMH在Linux上为您提供
-prof perfasm
,在Windows上为您提供
-prof xperfasm
。如果您在JDK 8u40上运行基准测试,那么您将看到(注意,我使用
-bm avgt-tu ns
使分数更容易理解):

为什么这些基准表现不同?让我们首先进行
-prof perfnorm
剖析(我删除了无关紧要的行):

因此,
ConstantSize
以某种方式实现了更多的L1 dcache存储,但减少了一个LLC负载。嗯,这就是我们要寻找的,在恒定的情况下,更多的商店<代码>-prof perfasm方便地突出显示了装配中的热点零件:

默认值

  4.32%    6.36%   0x00007f7714bda2dc: movq   $0x1,(%rax)            ; alloc
  0.09%    0.04%   0x00007f7714bda2e3: prefetchnta 0x100(%r9)
  2.95%    1.48%   0x00007f7714bda2eb: movl   $0xf80022a9,0x8(%rax)
  0.38%    0.18%   0x00007f7714bda2f2: mov    %r11d,0xc(%rax)
  1.56%    3.02%   0x00007f7714bda2f6: prefetchnta 0x140(%r9)
  4.73%    2.71%   0x00007f7714bda2fe: prefetchnta 0x180(%r9)
ConstantSize

  0.58%    1.22%   0x00007facf921132b: movq   $0x1,(%r14)            ; alloc
  0.84%    0.72%   0x00007facf9211332: prefetchnta 0xc0(%r10)
  0.11%    0.13%   0x00007facf921133a: movl   $0xf80022a9,0x8(%r14)
  0.21%    0.68%   0x00007facf9211342: prefetchnta 0x100(%r10)
  0.50%    0.87%   0x00007facf921134a: movl   $0x20,0xc(%r14)
  0.53%    0.82%   0x00007facf9211352: mov    $0x10,%ecx
  0.04%    0.14%   0x00007facf9211357: xor    %rax,%rax
  0.34%    0.76%   0x00007facf921135a: shl    $0x3,%rcx
  0.50%    1.17%   0x00007facf921135e: rex.W rep stos %al,%es:(%rdi) ; zeroing
 29.49%   52.09%   0x00007facf9211361: prefetchnta 0x140(%r10)
  1.03%    0.53%   0x00007facf9211369: prefetchnta 0x180(%r10)  
所以有一个讨厌的
rex.W rep stos%al,%es:(%rdi)
消耗了大量时间。这会将新分配的数组归零。在
ConstantSize
测试中,JVM无法关联您正在覆盖整个目标数组,因此它必须在跳入实际数组副本之前将其预置零

如果您查看JDK 9b82(最新版本)上生成的代码,您将看到它以非零拷贝方式折叠两种模式,正如您可以通过
-prof perfasm
看到的,也可以通过
-prof perfnorm
确认:

Benchmark                                     Mode  Cnt    Score    Error  Units
ACB.SAC                                       avgt   50   14.156 ±  0.492  ns/op
ACB.SAC:·CPI                                  avgt    5    0.612 ±  0.144   #/op
ACB.SAC:·L1-dcache-load-misses                avgt    5    2.363 ±  0.341   #/op
ACB.SAC:·L1-dcache-loads                      avgt    5   28.350 ±  2.181   #/op
ACB.SAC:·L1-dcache-store-misses               avgt    5    2.287 ±  0.607   #/op
ACB.SAC:·L1-dcache-stores                     avgt    5   16.922 ±  3.402   #/op
ACB.SAC:·branches                             avgt    5   21.242 ±  5.914   #/op
ACB.SAC:·cycles                               avgt    5   67.168 ± 20.950   #/op
ACB.SAC:·instructions                         avgt    5  109.931 ± 35.905   #/op

ACB.SAC_ConstantSize                          avgt   50   13.763 ±  0.067  ns/op
ACB.SAC_ConstantSize:·CPI                     avgt    5    0.625 ±  0.024   #/op
ACB.SAC_ConstantSize:·L1-dcache-load-misses   avgt    5    2.376 ±  0.214   #/op
ACB.SAC_ConstantSize:·L1-dcache-loads         avgt    5   28.285 ±  2.127   #/op
ACB.SAC_ConstantSize:·L1-dcache-store-misses  avgt    5    2.335 ±  0.223   #/op
ACB.SAC_ConstantSize:·L1-dcache-stores        avgt    5   16.926 ±  1.467   #/op
ACB.SAC_ConstantSize:·branches                avgt    5   19.469 ±  0.869   #/op
ACB.SAC_ConstantSize:·cycles                  avgt    5   62.395 ±  3.898   #/op
ACB.SAC_ConstantSize:·instructions            avgt    5   99.891 ±  5.435   #/op

0.58% 1.22% 0x00007facf921132b: movq $0x1,(%r14) ; alloc 0.84% 0.72% 0x00007facf9211332: prefetchnta 0xc0(%r10) 0.11% 0.13% 0x00007facf921133a: movl $0xf80022a9,0x8(%r14) 0.21% 0.68% 0x00007facf9211342: prefetchnta 0x100(%r10) 0.50% 0.87% 0x00007facf921134a: movl $0x20,0xc(%r14) 0.53% 0.82% 0x00007facf9211352: mov $0x10,%ecx 0.04% 0.14% 0x00007facf9211357: xor %rax,%rax 0.34% 0.76% 0x00007facf921135a: shl $0x3,%rcx 0.50% 1.17% 0x00007facf921135e: rex.W rep stos %al,%es:(%rdi) ; zeroing 29.49% 52.09% 0x00007facf9211361: prefetchnta 0x140(%r10) 1.03% 0.53% 0x00007facf9211369: prefetchnta 0x180(%r10)

Benchmark                                     Mode  Cnt    Score    Error  Units
ACB.SAC                                       avgt   50   14.156 ±  0.492  ns/op
ACB.SAC:·CPI                                  avgt    5    0.612 ±  0.144   #/op
ACB.SAC:·L1-dcache-load-misses                avgt    5    2.363 ±  0.341   #/op
ACB.SAC:·L1-dcache-loads                      avgt    5   28.350 ±  2.181   #/op
ACB.SAC:·L1-dcache-store-misses               avgt    5    2.287 ±  0.607   #/op
ACB.SAC:·L1-dcache-stores                     avgt    5   16.922 ±  3.402   #/op
ACB.SAC:·branches                             avgt    5   21.242 ±  5.914   #/op
ACB.SAC:·cycles                               avgt    5   67.168 ± 20.950   #/op
ACB.SAC:·instructions                         avgt    5  109.931 ± 35.905   #/op

ACB.SAC_ConstantSize                          avgt   50   13.763 ±  0.067  ns/op
ACB.SAC_ConstantSize:·CPI                     avgt    5    0.625 ±  0.024   #/op
ACB.SAC_ConstantSize:·L1-dcache-load-misses   avgt    5    2.376 ±  0.214   #/op
ACB.SAC_ConstantSize:·L1-dcache-loads         avgt    5   28.285 ±  2.127   #/op
ACB.SAC_ConstantSize:·L1-dcache-store-misses  avgt    5    2.335 ±  0.223   #/op
ACB.SAC_ConstantSize:·L1-dcache-stores        avgt    5   16.926 ±  1.467   #/op
ACB.SAC_ConstantSize:·branches                avgt    5   19.469 ±  0.869   #/op
ACB.SAC_ConstantSize:·cycles                  avgt    5   62.395 ±  3.898   #/op
ACB.SAC_ConstantSize:·instructions            avgt    5   99.891 ±  5.435   #/op