Added verbose mode to follow benchmarks process (#3218)

This commit is contained in:
LepilkinaElena
2019-07-26 14:09:41 +03:00
committed by GitHub
parent 67f01540ed
commit af98a3db37
19 changed files with 164 additions and 13 deletions
+9
View File
@@ -117,6 +117,15 @@ To update the blackbox compiler tests set TeamCity build number in `gradle.prope
./gradlew :performance:ring:konanRun --filterRegex=String.*,Loop.* ./gradlew :performance:ring:konanRun --filterRegex=String.*,Loop.*
There us also verbose mode to follow progress of running benchmarks
./gradlew :performance:cinterop:konanRun --verbose
> Task :performance:cinterop:konanRun
[DEBUG] Warm up iterations for benchmark macros
[DEBUG] Running benchmark macros
...
There are also tasks for running benchmarks on JVM (pay attention, some benchmarks e.g. cinterop benchmarks can't be run on JVM) There are also tasks for running benchmarks on JVM (pay attention, some benchmarks e.g. cinterop benchmarks can't be run on JVM)
./gradlew :performance:jvmRun ./gradlew :performance:jvmRun
@@ -24,6 +24,9 @@ open class RunBenchmarksExecutableTask @Inject constructor() : DefaultTask() {
@Input @Input
@Option(option = "filterRegex", description = "Benchmarks to run, described by regular expressions (comma-separated)") @Option(option = "filterRegex", description = "Benchmarks to run, described by regular expressions (comma-separated)")
var filterRegex: String = "" var filterRegex: String = ""
@Input
@Option(option = "verbose", description = "Verbose mode of running benchmarks")
var verbose: Boolean = false
private var curArgs: List<String> = emptyList() private var curArgs: List<String> = emptyList()
private val curEnvironment: MutableMap<String, Any> = mutableMapOf() private val curEnvironment: MutableMap<String, Any> = mutableMapOf()
@@ -53,6 +56,9 @@ open class RunBenchmarksExecutableTask @Inject constructor() : DefaultTask() {
it.args = curArgs + filterArgs + filterRegexArgs it.args = curArgs + filterArgs + filterRegexArgs
it.environment = curEnvironment it.environment = curEnvironment
it.workingDir(workingDir) it.workingDir(workingDir)
if (verbose) {
it.args("-v")
}
if (output != null) if (output != null)
it.standardOutput = output it.standardOutput = output
} }
@@ -23,6 +23,9 @@ open class RunJvmTask : JavaExec() {
@Input @Input
@Option(option = "filterRegex", description = "Benchmarks to run, described by regular expressions (comma-separated)") @Option(option = "filterRegex", description = "Benchmarks to run, described by regular expressions (comma-separated)")
var filterRegex: String = "" var filterRegex: String = ""
@Input
@Option(option = "verbose", description = "Verbose mode of running benchmarks")
var verbose: Boolean = false
override fun configure(configureClosure: Closure<Any>): Task { override fun configure(configureClosure: Closure<Any>): Task {
return super.configure(configureClosure) return super.configure(configureClosure)
@@ -33,6 +36,9 @@ open class RunJvmTask : JavaExec() {
val filterRegexArgs = filterRegex.splitCommaSeparatedOption("-fr") val filterRegexArgs = filterRegex.splitCommaSeparatedOption("-fr")
args(filterArgs) args(filterArgs)
args(filterRegexArgs) args(filterRegexArgs)
if (verbose) {
args("-v")
}
exec() exec()
} }
@@ -25,6 +25,9 @@ open class RunKotlinNativeTask @Inject constructor(private val linkTask: KotlinN
@Input @Input
@Option(option = "filterRegex", description = "Benchmarks to run, described by regular expressions (comma-separated)") @Option(option = "filterRegex", description = "Benchmarks to run, described by regular expressions (comma-separated)")
var filterRegex: String = "" var filterRegex: String = ""
@Input
@Option(option = "verbose", description = "Verbose mode of running benchmarks")
var verbose: Boolean = false
private val argumentsList = mutableListOf<String>() private val argumentsList = mutableListOf<String>()
@@ -63,6 +66,9 @@ open class RunKotlinNativeTask @Inject constructor(private val linkTask: KotlinN
it.executable = linkTask.binary.outputFile.absolutePath it.executable = linkTask.binary.outputFile.absolutePath
it.args(argumentsList) it.args(argumentsList)
it.args("-f", benchmark) it.args("-f", benchmark)
if (verbose) {
it.args("-v")
}
it.standardOutput = output it.standardOutput = output
} }
output.toString().removePrefix("[").removeSuffix("]") output.toString().removePrefix("[").removeSuffix("]")
@@ -74,6 +74,8 @@ open class BenchmarkExtension @Inject constructor(val project: Project) {
var commonSrcDirs: Collection<Any> = emptyList() var commonSrcDirs: Collection<Any> = emptyList()
var jvmSrcDirs: Collection<Any> = emptyList() var jvmSrcDirs: Collection<Any> = emptyList()
var nativeSrcDirs: Collection<Any> = emptyList() var nativeSrcDirs: Collection<Any> = emptyList()
var mingwSrcDirs: Collection<Any> = emptyList()
var posixSrcDirs: Collection<Any> = emptyList()
var linkerOpts: Collection<String> = emptyList() var linkerOpts: Collection<String> = emptyList()
} }
@@ -107,7 +109,11 @@ open class BenchmarkingPlugin: Plugin<Project> {
afterEvaluate { afterEvaluate {
benchmark.let { benchmark.let {
commonMain.kotlin.srcDirs(*it.commonSrcDirs.toTypedArray()) commonMain.kotlin.srcDirs(*it.commonSrcDirs.toTypedArray())
nativeMain.kotlin.srcDirs(*it.nativeSrcDirs.toTypedArray()) if (HostManager.hostIsMingw) {
nativeMain.kotlin.srcDirs(*(it.nativeSrcDirs + it.mingwSrcDirs).toTypedArray())
} else {
nativeMain.kotlin.srcDirs(*(it.nativeSrcDirs + it.posixSrcDirs).toTypedArray())
}
jvmMain.kotlin.srcDirs(*it.jvmSrcDirs.toTypedArray()) jvmMain.kotlin.srcDirs(*it.jvmSrcDirs.toTypedArray())
} }
} }
@@ -128,7 +134,7 @@ open class BenchmarkingPlugin: Plugin<Project> {
private fun Project.configureNativeTarget(hostPreset: KotlinNativeTargetPreset) { private fun Project.configureNativeTarget(hostPreset: KotlinNativeTargetPreset) {
kotlin.targetFromPreset(hostPreset, NATIVE_TARGET_NAME) { kotlin.targetFromPreset(hostPreset, NATIVE_TARGET_NAME) {
compilations.getByName("main").kotlinOptions.freeCompilerArgs = project.compilerArgs + "-opt" compilations.getByName("main").kotlinOptions.freeCompilerArgs = project.compilerArgs
binaries.executable(NATIVE_EXECUTABLE_NAME, listOf(RELEASE)) { binaries.executable(NATIVE_EXECUTABLE_NAME, listOf(RELEASE)) {
if (HostManager.hostIsMingw) { if (HostManager.hostIsMingw) {
linkerOpts.add("-L${mingwPath}/lib") linkerOpts.add("-L${mingwPath}/lib")
+3 -1
View File
@@ -13,7 +13,9 @@ benchmark {
applicationName = "Cinterop" applicationName = "Cinterop"
commonSrcDirs = listOf("../../tools/benchmarks/shared/src", "src/main/kotlin", "../shared/src/main/kotlin") commonSrcDirs = listOf("../../tools/benchmarks/shared/src", "src/main/kotlin", "../shared/src/main/kotlin")
jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm") jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm")
nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native") nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/common")
mingwSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/mingw")
posixSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/posix")
} }
val native = kotlin.targets.getByName("native") as KotlinNativeTarget val native = kotlin.targets.getByName("native") as KotlinNativeTarget
+1 -1
View File
@@ -42,7 +42,7 @@ fun main(args: Array<String>) {
BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments -> BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments ->
if (arguments is BaseBenchmarkArguments) { if (arguments is BaseBenchmarkArguments) {
launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix, launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix,
arguments.filter, arguments.filterRegex) arguments.filter, arguments.filterRegex, arguments.verbose)
} else emptyList() } else emptyList()
}, benchmarksListAction = launcher::benchmarksListAction) }, benchmarksListAction = launcher::benchmarksListAction)
} }
+3 -1
View File
@@ -16,7 +16,9 @@ benchmark {
applicationName = "ObjCInterop" applicationName = "ObjCInterop"
commonSrcDirs = listOf("../../tools/benchmarks/shared/src", "src/main/kotlin", "../shared/src/main/kotlin") commonSrcDirs = listOf("../../tools/benchmarks/shared/src", "src/main/kotlin", "../shared/src/main/kotlin")
jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm") jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm")
nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native") nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/common")
mingwSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/mingw")
posixSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/posix")
linkerOpts = listOf("-L$buildDir", "-lcomplexnumbers") linkerOpts = listOf("-L$buildDir", "-lcomplexnumbers")
} }
@@ -29,7 +29,7 @@ fun main(args: Array<String>) {
BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments -> BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments ->
if (arguments is BaseBenchmarkArguments) { if (arguments is BaseBenchmarkArguments) {
launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix, launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix,
arguments.filter, arguments.filterRegex) arguments.filter, arguments.filterRegex, arguments.verbose)
} else emptyList() } else emptyList()
}, benchmarksListAction = launcher::benchmarksListAction) }, benchmarksListAction = launcher::benchmarksListAction)
} }
+3 -1
View File
@@ -11,5 +11,7 @@ benchmark {
applicationName = "Ring" applicationName = "Ring"
commonSrcDirs = listOf("../../tools/benchmarks/shared/src", "src/main/kotlin", "../shared/src/main/kotlin", "../../endorsedLibraries/kliopt/src/main/kotlin") commonSrcDirs = listOf("../../tools/benchmarks/shared/src", "src/main/kotlin", "../shared/src/main/kotlin", "../../endorsedLibraries/kliopt/src/main/kotlin")
jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm", "../../endorsedLibraries/kliopt/src/main/kotlin-jvm") jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm", "../../endorsedLibraries/kliopt/src/main/kotlin-jvm")
nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native", "../../endorsedLibraries/kliopt/src/main/kotlin-native") nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/common", "../../endorsedLibraries/kliopt/src/main/kotlin-native")
mingwSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/mingw")
posixSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/posix")
} }
+1 -1
View File
@@ -212,7 +212,7 @@ fun main(args: Array<String>) {
BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments -> BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments ->
if (arguments is BaseBenchmarkArguments) { if (arguments is BaseBenchmarkArguments) {
launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix, launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix,
arguments.filter, arguments.filterRegex) arguments.filter, arguments.filterRegex, arguments.verbose)
} else emptyList() } else emptyList()
}, benchmarksListAction = launcher::benchmarksListAction) }, benchmarksListAction = launcher::benchmarksListAction)
} }
@@ -17,6 +17,8 @@
package org.jetbrains.benchmarksLauncher package org.jetbrains.benchmarksLauncher
import java.io.File import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
actual fun writeToFile(fileName: String, text: String) { actual fun writeToFile(fileName: String, text: String) {
File(fileName).printWriter().use { out -> File(fileName).printWriter().use { out ->
@@ -36,3 +38,10 @@ actual inline fun measureNanoTime(block: () -> Unit): Long {
actual fun cleanup() {} actual fun cleanup() {}
actual fun printStderr(message: String) {
System.err.print(message)
}
actual fun currentTime(): String =
SimpleDateFormat("HH:mm:ss").format(Date())
@@ -18,6 +18,7 @@ package org.jetbrains.benchmarksLauncher
import kotlin.native.internal.GC import kotlin.native.internal.GC
import platform.posix.* import platform.posix.*
import kotlinx.cinterop.*
actual fun writeToFile(fileName: String, text: String) { actual fun writeToFile(fileName: String, text: String) {
val file = fopen(fileName, "wt") ?: error("Cannot write file '$fileName'") val file = fopen(fileName, "wt") ?: error("Cannot write file '$fileName'")
@@ -41,3 +42,10 @@ actual inline fun measureNanoTime(block: () -> Unit): Long {
actual fun cleanup() { actual fun cleanup() {
GC.collect() GC.collect()
} }
actual fun printStderr(message: String) {
val STDERR = fdopen(2, "w")
fprintf(STDERR, message)
fflush(STDERR)
}
@@ -0,0 +1,34 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.benchmarksLauncher
import platform.posix.*
import platform.windows.*
import kotlinx.cinterop.*
actual fun currentTime() =
memScoped {
val timeVal = alloc<timeval>()
mingw_gettimeofday(timeVal.ptr, null)
val sec = alloc<LongVar>()
sec.value = timeVal.tv_sec.convert()
val nowtm = localtime(sec.ptr)
var timeBuffer = ByteArray(1024)
strftime(timeBuffer.refTo(0), timeBuffer.size.toULong(), "%H:%M:%S", nowtm)
timeBuffer.toKString()
}
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.benchmarksLauncher
import platform.posix.*
import kotlinx.cinterop.*
actual fun currentTime() =
memScoped {
val timeVal = alloc<timeval>()
gettimeofday(timeVal.ptr, null)
val sec = alloc<LongVar>()
sec.value = timeVal.tv_sec
val nowtm = localtime(sec.ptr)
var timeBuffer = ByteArray(1024)
strftime(timeBuffer.refTo(0), timeBuffer.size.toULong(), "%H:%M:%S", nowtm)
timeBuffer.toKString()
}
@@ -23,3 +23,7 @@ expect fun assert(value: Boolean)
expect inline fun measureNanoTime(block: () -> Unit): Long expect inline fun measureNanoTime(block: () -> Unit): Long
expect fun cleanup() expect fun cleanup()
expect fun printStderr(message: String)
expect fun currentTime(): String
@@ -46,11 +46,28 @@ abstract class Launcher {
} }
} }
enum class LogLevel { DEBUG, OFF }
class Logger(val level: LogLevel = LogLevel.OFF) {
fun log(message: String, messageLevel: LogLevel = LogLevel.DEBUG, usePrefix: Boolean = true) {
if (messageLevel == level) {
if (usePrefix) {
printStderr("[$level][${currentTime()}] $message")
} else {
printStderr("$message")
}
}
}
}
fun launch(numWarmIterations: Int, fun launch(numWarmIterations: Int,
numberOfAttempts: Int, numberOfAttempts: Int,
prefix: String = "", prefix: String = "",
filters: Collection<String>? = null, filters: Collection<String>? = null,
filterRegexes: Collection<String>? = null): List<BenchmarkResult> { filterRegexes: Collection<String>? = null,
verbose: Boolean): List<BenchmarkResult> {
val logger = if (verbose) Logger(LogLevel.DEBUG) else Logger()
val regexes = filterRegexes?.map { it.toRegex() } ?: listOf() val regexes = filterRegexes?.map { it.toRegex() } ?: listOf()
val filterSet = filters?.toHashSet() ?: hashSetOf() val filterSet = filters?.toHashSet() ?: hashSetOf()
// Filter benchmarks using given filters, or run all benchmarks if none were given. // Filter benchmarks using given filters, or run all benchmarks if none were given.
@@ -63,6 +80,7 @@ abstract class Launcher {
for ((name, benchmark) in runningBenchmarks) { for ((name, benchmark) in runningBenchmarks) {
val benchmarkInstance = (benchmark as? BenchmarkEntryWithInit)?.ctor?.invoke() val benchmarkInstance = (benchmark as? BenchmarkEntryWithInit)?.ctor?.invoke()
var i = numWarmIterations var i = numWarmIterations
logger.log("Warm up iterations for benchmark $name\n")
runBenchmark(benchmarkInstance, benchmark, i) runBenchmark(benchmarkInstance, benchmark, i)
var autoEvaluatedNumberOfMeasureIteration = 1 var autoEvaluatedNumberOfMeasureIteration = 1
while (true) { while (true) {
@@ -72,8 +90,10 @@ abstract class Launcher {
break break
autoEvaluatedNumberOfMeasureIteration *= 2 autoEvaluatedNumberOfMeasureIteration *= 2
} }
logger.log("Running benchmark $name ")
val samples = DoubleArray(numberOfAttempts) val samples = DoubleArray(numberOfAttempts)
for (k in samples.indices) { for (k in samples.indices) {
logger.log(".", usePrefix = false)
i = autoEvaluatedNumberOfMeasureIteration i = autoEvaluatedNumberOfMeasureIteration
val time = runBenchmark(benchmarkInstance, benchmark, i) val time = runBenchmark(benchmarkInstance, benchmark, i)
val scaledTime = time * 1.0 / autoEvaluatedNumberOfMeasureIteration val scaledTime = time * 1.0 / autoEvaluatedNumberOfMeasureIteration
@@ -83,6 +103,7 @@ abstract class Launcher {
scaledTime / 1000, BenchmarkResult.Metric.EXECUTION_TIME, scaledTime / 1000, scaledTime / 1000, BenchmarkResult.Metric.EXECUTION_TIME, scaledTime / 1000,
k + 1, numWarmIterations)) k + 1, numWarmIterations))
} }
logger.log("\n", usePrefix = false)
} }
return benchmarkResults return benchmarkResults
} }
@@ -107,6 +128,7 @@ class BaseBenchmarkArguments(argParser: ArgParser): BenchmarkArguments(argParser
val filter by argParser.options(ArgType.String, shortName = "f", description = "Benchmark to run", multiple = true) val filter by argParser.options(ArgType.String, shortName = "f", description = "Benchmark to run", multiple = true)
val filterRegex by argParser.options(ArgType.String, shortName = "fr", val filterRegex by argParser.options(ArgType.String, shortName = "fr",
description = "Benchmark to run, described by a regular expression", multiple = true) description = "Benchmark to run, described by a regular expression", multiple = true)
val verbose by argParser.option(ArgType.Boolean, shortName = "v", description = "Verbose mode of running", defaultValue = false)
} }
object BenchmarksRunner { object BenchmarksRunner {
+2 -1
View File
@@ -44,7 +44,8 @@ kotlin {
} }
macosMain { macosMain {
dependsOn commonMain dependsOn commonMain
kotlin.srcDir "../shared/src/main/kotlin-native" kotlin.srcDir "../shared/src/main/kotlin-native/common"
kotlin.srcDir "../shared/src/main/kotlin-native/posix"
kotlin.srcDir "$rootProject.projectDir/endorsedLibraries/kliopt/src/main/kotlin-native" kotlin.srcDir "$rootProject.projectDir/endorsedLibraries/kliopt/src/main/kotlin-native"
} }
} }
+2 -1
View File
@@ -43,7 +43,8 @@ runner.runBenchmarks(args: args, run: { (arguments: BenchmarkArguments) -> [Benc
return swiftLauncher.launch(numWarmIterations: argumentsList.warmup, return swiftLauncher.launch(numWarmIterations: argumentsList.warmup,
numberOfAttempts: argumentsList.repeat, numberOfAttempts: argumentsList.repeat,
prefix: argumentsList.prefix, filters: argumentsList.filter, prefix: argumentsList.prefix, filters: argumentsList.filter,
filterRegexes: argumentsList.filterRegex) filterRegexes: argumentsList.filterRegex,
verbose: argumentsList.verbose)
} }
return [BenchmarkResult]() return [BenchmarkResult]()
}, parseArgs: { (args: KotlinArray, benchmarksListAction: (() -> KotlinUnit)) -> BenchmarkArguments? in }, parseArgs: { (args: KotlinArray, benchmarksListAction: (() -> KotlinUnit)) -> BenchmarkArguments? in