From b01ef8465a3a32b5de5be508429c40532a6f7d1c Mon Sep 17 00:00:00 2001 From: "Aleksei.Glushko" Date: Wed, 1 Feb 2023 15:16:09 +0000 Subject: [PATCH] [K/N] Add ring/GenericArrayView bench also .gitignore cmake-build-debug on all levels Merge-request: KT-MR-8412 Merged-by: Alexey Glushko --- kotlin-native/.gitignore | 2 +- .../performance/ring/src/main/kotlin/main.kt | 4 + .../ring/GenericArrayViewBenchmark.kt | 73 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 kotlin-native/performance/ring/src/main/kotlin/org/jetbrains/ring/GenericArrayViewBenchmark.kt diff --git a/kotlin-native/.gitignore b/kotlin-native/.gitignore index 3f2bb079a53..dd5bba727cb 100644 --- a/kotlin-native/.gitignore +++ b/kotlin-native/.gitignore @@ -60,7 +60,7 @@ samples/**/*.kt.bc-build tools/performance-server/node_modules tools/performance-server/server tools/performance-server/ui/js -runtime/cmake-build-debug/ +cmake-build-debug/ # compilation database compile_commands.json diff --git a/kotlin-native/performance/ring/src/main/kotlin/main.kt b/kotlin-native/performance/ring/src/main/kotlin/main.kt index 30651c68c44..e109050db12 100644 --- a/kotlin-native/performance/ring/src/main/kotlin/main.kt +++ b/kotlin-native/performance/ring/src/main/kotlin/main.kt @@ -229,6 +229,10 @@ class RingLauncher : Launcher() { "Calls.interfaceMethodHexamorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { interfaceMethodCall_HexamorphicCallsite() }), "LocalObjects.localArray" to BenchmarkEntryWithInit.create(::LocalObjectsBenchmark, { localArray() }), "ComplexArrays.outerProduct" to BenchmarkEntryWithInit.create(::ComplexArraysBenchmark, { outerProduct() }), + "GenericArrayView.origin" to BenchmarkEntryWithInit.create(::GenericArrayViewBenchmark, { origin() }), + "GenericArrayView.inlined" to BenchmarkEntryWithInit.create(::GenericArrayViewBenchmark, { inlined() }), + "GenericArrayView.specialized" to BenchmarkEntryWithInit.create(::GenericArrayViewBenchmark, { specialized() }), + "GenericArrayView.manual" to BenchmarkEntryWithInit.create(::GenericArrayViewBenchmark, { manual() }), "WeakRefBenchmark.aliveReference" to BenchmarkEntryWithInit.create(::WeakRefBenchmark, { aliveReference() }), "WeakRefBenchmark.deadReference" to BenchmarkEntryWithInit.create(::WeakRefBenchmark, { deadReference() }), "WeakRefBenchmark.dyingReference" to BenchmarkEntryWithInit.create(::WeakRefBenchmark, { dyingReference() }), diff --git a/kotlin-native/performance/ring/src/main/kotlin/org/jetbrains/ring/GenericArrayViewBenchmark.kt b/kotlin-native/performance/ring/src/main/kotlin/org/jetbrains/ring/GenericArrayViewBenchmark.kt new file mode 100644 index 00000000000..84fd5a2d6d0 --- /dev/null +++ b/kotlin-native/performance/ring/src/main/kotlin/org/jetbrains/ring/GenericArrayViewBenchmark.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +import org.jetbrains.benchmarksLauncher.Blackhole +import org.jetbrains.benchmarksLauncher.Random + +// Benchmark is inspired by multik library. + +interface MemoryView where T : Number { + fun get(index: Int): T +} + +class MemoryViewIntArray(val data: IntArray) : MemoryView { + override fun get(index: Int): Int = data[index] +} + +class MemoryViewLongArray(val data: LongArray) : MemoryView { + override fun get(index: Int): Long = data[index] +} + +class MemoryViewDoubleArray(val data: DoubleArray) : MemoryView { + override fun get(index: Int): Double = data[index] +} + +class Array2D(val data: MemoryView, val width: Int) where T : Number{ + fun getGeneric(ind1: Int, ind2: Int): Int { + return data.get(width * ind1 + ind2).toInt() + } + + inline fun getGenericInlined(ind1: Int, ind2: Int): Int { + return data.get(width * ind1 + ind2).toInt() + } + + inline fun getSpecializedInlined(ind1: Int, ind2: Int): Int { + return (data as MemoryViewIntArray).get(width * ind1 + ind2) + } +} + +open class GenericArrayViewBenchmark { + private val N = 2000 + + private val intArr = Array2D(MemoryViewIntArray(IntArray(N * N) { Random.nextInt() }), N) + // To confuse devirtualizer: + private val longArr = Array2D(MemoryViewLongArray(LongArray(N * N) { Random.nextInt().toLong() }), N) + private val doubleArr = Array2D(MemoryViewDoubleArray(DoubleArray(N * N) { Random.nextDouble() }), N) + + init { + bench(longArr) { a, i, j -> a.getGeneric(i, j) } + bench(doubleArr) { a, i, j -> a.getGenericInlined(i, j) } + try { bench(longArr) { a, i, j -> a.getSpecializedInlined(i, j) } } catch (t: ClassCastException) {} + } + + private inline fun bench(arr: Array2D, getter: (Array2D, Int, Int) -> Int) where T : Number { + var sum = 0 + + for (i in 0 until N) { + for (j in 0 until N) { + sum += getter(arr, i, j) + } + } + + Blackhole.consume(sum) + } + + // Bench cases: + + fun origin() { bench(intArr) { a, i, j -> a.getGeneric(i, j) } } + fun inlined() { bench(intArr) { a, i, j -> a.getGenericInlined(i, j) } } + fun specialized() { bench(intArr) { a, i, j -> a.getSpecializedInlined(i, j) } } + fun manual() { bench(intArr) { a, i, j -> a.width * i + j } } +}