什么是 StubRoutines::jbyte_disjoint_arraycopy
What is StubRoutines::jbyte_disjoint_arraycopy
我正在测量一些单线程方法调用(用 Scala 编写)并想分析基准。这是它的样子(省略了实现细节)
@State(Scope.Benchmark)
class TheBenchmarks {
var data: Array[Byte] = _
@Param(Array("1024", "2048", "4096", "8192"))
var chunkSize: Int = _
@Setup
def setup(): Unit = {
data = //get the data
}
@Benchmark
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@BenchmarkMode(Array(Mode.AverageTime))
def takeFirstAvroRecord(bh: Blackhole): Unit = {
val fr = //do computation with data and chunk size
bh.consume(fr)
}
}
好的,我得到了一些结果并想了解它,但是 -prof perfasm
的输出对我来说有点不清楚。首先:
....[Hottest Regions]...............................................................................
44.20% 40.50% runtime stub StubRoutines::jbyte_disjoint_arraycopy (205 bytes)
6.78% 1.62% C2, level 4 cats.data.IndexedStateT$$Lambda::apply, version 1242 (967 bytes)
4.39% 0.79% C2, level 4 my.pack.age.Mclass::cut0, version 1323 (299 bytes)
和
....[Hottest Methods (after inlining)]..............................................................
44.20% 40.50% runtime stub StubRoutines::jbyte_disjoint_arraycopy
8.40% 3.93% C2, level 4 cats.data.IndexedStateT$$Lambda::apply, version 1242
5.76% 2.67% C2, level 4 my.pack.age.Mclass::cut0, version 1323
我找到了一些关于 jbyte_disjoint_arraycopy
的信息。声明如下here如下
StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry,
"jbyte_disjoint_arraycopy");
从 generate_disjoint_byte_copy
方法的来源来看,它看起来像是汇编代码生成的东西...我猜它是 x86
...[=21 的一些内部数组副本=]
问题:能否请您解释一下StubRoutines
以及什么可能导致它成为最热的区域?
你猜对了。 <type>_disjoint_arraycopy
存根是在 运行 时间内生成的函数,专门用于加速 System.arraycopy
调用。
当 JVM 启动时,它会使用当前可用的 CPU features. E.g. if CPU supports AVX2, generated arraycopy
stubs will make use of AVX2 instructions.
为某些例程生成优化的机器代码
System.arraycopy
是 HotSpot 内在方法。当由 C2 编译时,System.arraycopy
的调用执行必要的检查,然后调用生成的 arraycopy
存根例程之一。
如果 StubRoutines::jbyte_disjoint_arraycopy
是最热的区域,这基本上意味着您的基准测试大部分时间都在 System.arraycopy
内处理 byte[]
数组。您可以尝试 async-profiler 看看这个 arraycopy
是从哪里调用的。
我正在测量一些单线程方法调用(用 Scala 编写)并想分析基准。这是它的样子(省略了实现细节)
@State(Scope.Benchmark)
class TheBenchmarks {
var data: Array[Byte] = _
@Param(Array("1024", "2048", "4096", "8192"))
var chunkSize: Int = _
@Setup
def setup(): Unit = {
data = //get the data
}
@Benchmark
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@BenchmarkMode(Array(Mode.AverageTime))
def takeFirstAvroRecord(bh: Blackhole): Unit = {
val fr = //do computation with data and chunk size
bh.consume(fr)
}
}
好的,我得到了一些结果并想了解它,但是 -prof perfasm
的输出对我来说有点不清楚。首先:
....[Hottest Regions]...............................................................................
44.20% 40.50% runtime stub StubRoutines::jbyte_disjoint_arraycopy (205 bytes)
6.78% 1.62% C2, level 4 cats.data.IndexedStateT$$Lambda::apply, version 1242 (967 bytes)
4.39% 0.79% C2, level 4 my.pack.age.Mclass::cut0, version 1323 (299 bytes)
和
....[Hottest Methods (after inlining)]..............................................................
44.20% 40.50% runtime stub StubRoutines::jbyte_disjoint_arraycopy
8.40% 3.93% C2, level 4 cats.data.IndexedStateT$$Lambda::apply, version 1242
5.76% 2.67% C2, level 4 my.pack.age.Mclass::cut0, version 1323
我找到了一些关于 jbyte_disjoint_arraycopy
的信息。声明如下here如下
StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry,
"jbyte_disjoint_arraycopy");
从 generate_disjoint_byte_copy
方法的来源来看,它看起来像是汇编代码生成的东西...我猜它是 x86
...[=21 的一些内部数组副本=]
问题:能否请您解释一下StubRoutines
以及什么可能导致它成为最热的区域?
你猜对了。 <type>_disjoint_arraycopy
存根是在 运行 时间内生成的函数,专门用于加速 System.arraycopy
调用。
当 JVM 启动时,它会使用当前可用的 CPU features. E.g. if CPU supports AVX2, generated arraycopy
stubs will make use of AVX2 instructions.
System.arraycopy
是 HotSpot 内在方法。当由 C2 编译时,System.arraycopy
的调用执行必要的检查,然后调用生成的 arraycopy
存根例程之一。
如果 StubRoutines::jbyte_disjoint_arraycopy
是最热的区域,这基本上意味着您的基准测试大部分时间都在 System.arraycopy
内处理 byte[]
数组。您可以尝试 async-profiler 看看这个 arraycopy
是从哪里调用的。