From 53a0a09db0fc69421993e4cea9e884f8d9b25656 Mon Sep 17 00:00:00 2001 From: tochilinak Date: Thu, 19 Jun 2025 12:54:02 +0300 Subject: [PATCH 1/4] add time profiling --- .../usvm/statistics/UDebugProfileObserver.kt | 112 ++++++++++++++---- .../machine/utils/PyDebugProfileObserver.kt | 2 + 2 files changed, 90 insertions(+), 24 deletions(-) diff --git a/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt b/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt index 91467ef299..992450af12 100644 --- a/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt +++ b/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt @@ -79,18 +79,42 @@ open class UDebugProfileObserver>() protected val methodCalls = hashMapOf>() - private val stackTraceTracker = StackTraceTracker(statementOperations) + private val stackTraceTracker = StackTraceTracker(statementOperations) private val stackTraces = hashMapOf, MutableMap>() private val forksCount = hashMapOf, MutableMap>() + private val instructionTime = hashMapOf, MutableMap>() + + private var lastPeekMoment = 0L + private var lastStackTrace: TrieNode? = null override fun onStatePeeked(state: State) { - if (profilerOptions.momentOfUpdate == MomentOfUpdate.BeforeStep) { - processStateUpdate(state) + if (profilerOptions.momentOfUpdate != MomentOfUpdate.BeforeStep) { + return + } + + processStateUpdate(state) + + if (profilerOptions.profileTime) { + lastPeekMoment = System.currentTimeMillis() } } @@ -100,6 +124,20 @@ open class UDebugProfileObserver, time: Long) { + var st = stackTrace + while (true) { + instructionTime.increment(st, state, value = time) + st = st.parent() ?: break + } } private fun processStateUpdate(state: State) { @@ -124,6 +162,7 @@ open class UDebugProfileObserver MutableMap>.increment(key: K, state: State) { + private fun MutableMap>.increment(key: K, state: State, value: Long = 1L) { val stateStats = this.getOrPut(key) { hashMapOf() } val stats = stateStats.getOrPut(state.id) { StatsCounter() } - stats.increment() + stats.add(value) } private fun aggregateStackTraces(slice: StateId?): ProfileFrame { @@ -143,10 +182,12 @@ open class UDebugProfileObserver { val allNodeStats = stackTraces[root].orEmpty() val allForkStats = forksCount[root].orEmpty() + val allTimeStats = instructionTime[root].orEmpty() val children = root.children.mapValues { (i, node) -> computeProfileFrame(slice, i, node) } val nodeStats = allNodeStats.sumOfSlice(slice) val forkStats = allForkStats.sumOfSlice(slice) + val timeStats = allTimeStats.sumOfSlice(slice) - val selfStat = nodeStats - children.values.sumOf { it.total } + val selfStat = nodeStats - children.values.sumOf { it.totalSteps } val selfForks = forkStats - children.values.sumOf { it.totalForks } + val selfTime = timeStats - children.values.sumOf { it.totalTime } return ProfileFrame( inst, - nodeStats, - selfStat, - forkStats, - selfForks, + totalSteps = nodeStats, + selfSteps = selfStat, + totalForks = forkStats, + selfForks = selfForks, + totalTime = timeStats, + selfTime = selfTime, children, profilerOptions, statementOperations, @@ -181,10 +227,12 @@ open class UDebugProfileObserver>( val inst: Statement?, - val total: Long, - val self: Long, + val totalSteps: Long, + val selfSteps: Long, val totalForks: Long, val selfForks: Long, + val totalTime: Long, + val selfTime: Long, val children: Map>, private val profilerOptions: Options, private val statementOperations: StatementOperations, @@ -192,15 +240,23 @@ open class UDebugProfileObserver entry.value.sumOf { it.value.total } } + .sortedByDescending { entry -> entry.value.sumOf { it.value.totalSteps } } for ((method, inst) in sortedChildren) { - val total = inst.sumOf { it.value.total } - val self = inst.sumOf { it.value.self } + val total = inst.sumOf { it.value.totalSteps } + val self = inst.sumOf { it.value.selfSteps } val totalForks = inst.sumOf { it.value.totalForks } val selfForks = inst.sumOf { it.value.selfForks } val methodRepr = statementOperations.printMethodName(method) - str.appendLine("$indent|__ $methodRepr | Steps $self/$total | Forks $selfForks/$totalForks") + + str.append("$indent|__ $methodRepr | Steps $self/$total") + if (profilerOptions.profileForks) { + str.append(" | Forks $selfForks/$totalForks") + } + if (profilerOptions.profileTime) { + str.append(" | Time $selfTime/$totalTime") + } + str.appendLine() val children = if (profilerOptions.printNonVisitedStatements) { val allStatements = statementOperations.getAllMethodStatements(method) @@ -212,10 +268,12 @@ open class UDebugProfileObserver Date: Thu, 19 Jun 2025 14:57:14 +0300 Subject: [PATCH 2/4] Timing in nanoseconds --- .../usvm/statistics/UDebugProfileObserver.kt | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt b/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt index 992450af12..0b3418ebae 100644 --- a/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt +++ b/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt @@ -87,6 +87,7 @@ open class UDebugProfileObserver time + TimeFormat.Microseconds -> time / 1000L + TimeFormat.Milliseconds -> time / 1000000L + } + } + private fun computeProfileFrame( slice: StateId?, inst: Statement, @@ -217,8 +226,8 @@ open class UDebugProfileObserver Date: Thu, 19 Jun 2025 15:11:22 +0300 Subject: [PATCH 3/4] detekt fix --- .../kotlin/org/usvm/statistics/UDebugProfileObserver.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt b/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt index 0b3418ebae..9efca55224 100644 --- a/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt +++ b/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt @@ -198,8 +198,8 @@ open class UDebugProfileObserver time - TimeFormat.Microseconds -> time / 1000L - TimeFormat.Milliseconds -> time / 1000000L + TimeFormat.Microseconds -> time / MICRO_IN_NANO + TimeFormat.Milliseconds -> time / MILLIES_IN_NANO } } @@ -367,4 +367,9 @@ open class UDebugProfileObserver Date: Thu, 19 Jun 2025 15:30:06 +0300 Subject: [PATCH 4/4] detekt fix --- .../main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt b/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt index 9efca55224..145e3907be 100644 --- a/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt +++ b/usvm-core/src/main/kotlin/org/usvm/statistics/UDebugProfileObserver.kt @@ -370,6 +370,6 @@ open class UDebugProfileObserver