OK, here is an alternative way:
Pack every variable that is related with stats to $statsInfo,
and make it a dynamic variable, along side with $timedNameStack.
(Otherwise we have to make 5 dynamic variables.)
Basically move the topFrame into an individual variable.
See attachment.
- Qian
On 1/17/24 08:55, Waldek Hebisch wrote:
On Tue, Jan 16, 2024 at 07:32:56PM +0800, Qian Yun wrote:
This is the second patch (of two) to enable correct collection
of statistics information on recursive calls to interpreter.
Move $statsInfo and other global variables required for timing
to the top of $timedNameStack.
Since $timedNameStack now has dynamic scope, recursive timing
is correctly supported after this patch.
This business with 'topFrame' looks fishy. Stack should be
a stack, but you effectively turn top item into a global
variable and push below it. I did not analyzed the whole
of the patch, but ATM moment my feeling is "there should be
better way".
--
You received this message because you are subscribed to the Google Groups "FriCAS -
computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/fricas-devel/084af024-56c3-4305-94a1-63e64b9bd24f%40gmail.com.
From 1a814d4d174a4b395e70ef0244a835417fdd8637 Mon Sep 17 00:00:00 2001
From: Qian Yun <[email protected]>
Date: Wed, 13 Dec 2023 18:00:09 +0800
Subject: [PATCH] Store stats information in $statsInfo instead of global
variables
---
src/interp/g-timer.boot | 43 ++++++++++++++--------------------------
src/interp/i-toplev.boot | 1 +
2 files changed, 16 insertions(+), 28 deletions(-)
diff --git a/src/interp/g-timer.boot b/src/interp/g-timer.boot
index 51d0846a7..fba145ca9 100644
--- a/src/interp/g-timer.boot
+++ b/src/interp/g-timer.boot
@@ -104,15 +104,12 @@ stopTimingProcess name ==
popTimedName()
--% Instrumentation specific to the interpreter
-DEFPARAMETER($oldElapsedSpace, 0)
-DEFPARAMETER($oldElapsedGCTime, 0.0)
-DEFPARAMETER($oldElapsedTime, 0.0)
DEFPARAMETER($timePrintDigits, 2)
-- $timedNameStack is used to hold the names of sections of the
-- code being timed.
-DEFPARAMETER($timedNameStack, '(other))
+DEFVAR($timedNameStack)
DEFPARAMETER($interpreterTimedNames, '(
-- name class abbrev
@@ -148,27 +145,33 @@ DEFPARAMETER($interpreterTimedClasses, '(
DEFVAR($statsInfo)
initializeTimedNames() ==
- len := # $interpreterTimedNames
- $statsInfo := VECTOR(GETZEROVEC len, GETZEROVEC len)
for [name, :.] in $interpreterTimedNames for i in 0.. repeat
PUT(name, 'index, i)
initializeTimedStack()
initializeTimedStack() ==
$timedNameStack := '(other)
- computeElapsedTime()
- computeElapsedSpace()
+ len := # $interpreterTimedNames
+ $statsInfo := VECTOR(GETZEROVEC len, GETZEROVEC len, get_run_time(), _
+ elapsedGcTime(), HEAPELAPSED())
NIL
updateTimedName name ==
+ oldTime := $statsInfo.2
+ oldGCTime := $statsInfo.3
+ oldSpace := $statsInfo.4
+ newTime := $statsInfo.2 := get_run_time()
+ newGCTime := $statsInfo.3 := elapsedGcTime()
+ newSpace := $statsInfo.4 := HEAPELAPSED()
+
i := GET(name, 'index)
timeVec := $statsInfo.0
spaceVec := $statsInfo.1
- [time, gcTime] := computeElapsedTime()
- timeVec.i := timeVec.i + time
+ gcDelta := newGCTime - oldGCTime
+ timeVec.i := timeVec.i + (newTime - oldTime - gcDelta)*$inverseTimerTicksPerSecond
i2 := GET('gc, 'index)
- timeVec.i2 := timeVec.i2 + gcTime
- spaceVec.i := spaceVec.i + computeElapsedSpace()
+ timeVec.i2 := timeVec.i2 + gcDelta * $inverseTimerTicksPerSecond
+ spaceVec.i := spaceVec.i + newSpace - oldSpace
makeLongTimeString(listofnames,listofclasses) ==
makeLongStatStringByProperty(listofnames, listofclasses, _
@@ -182,22 +185,6 @@ makeLongSpaceString(listofnames,listofclasses) ==
DEFPARAMETER($inverseTimerTicksPerSecond, 1.0/$timerTicksPerSecond)
-computeElapsedTime() ==
- currentTime:= get_run_time()
- currentGCTime:= elapsedGcTime()
- gcDelta := currentGCTime - $oldElapsedGCTime
- elapsedSeconds:= $inverseTimerTicksPerSecond *
- (currentTime-$oldElapsedTime-gcDelta)
- $oldElapsedTime := currentTime
- $oldElapsedGCTime := currentGCTime
- [elapsedSeconds, $inverseTimerTicksPerSecond * gcDelta]
-
-computeElapsedSpace() ==
- currentElapsedSpace := HEAPELAPSED()
- elapsedBytes := currentElapsedSpace - $oldElapsedSpace
- $oldElapsedSpace := currentElapsedSpace
- elapsedBytes
-
timedAlgebraEvaluation(code) ==
startTimingProcess 'algebra
r := eval code
diff --git a/src/interp/i-toplev.boot b/src/interp/i-toplev.boot
index de9a472d3..a26930aea 100644
--- a/src/interp/i-toplev.boot
+++ b/src/interp/i-toplev.boot
@@ -128,6 +128,7 @@ DEFPARAMETER($inRetract, nil)
processInteractive(form, posnForm) ==
$timedNameStack : local := NIL
+ $statsInfo : local := NIL
initializeTimedStack()
finally(
object := processInteractive0(form, posnForm),
From ec2ce411e0300fd0b3a59ed8055110f13567a244 Mon Sep 17 00:00:00 2001
From: Qian Yun <[email protected]>
Date: Wed, 13 Dec 2023 18:00:09 +0800
Subject: [PATCH] Do not store stats information into symbol plist
---
src/interp/g-timer.boot | 57 ++++++++++++++++++++++------------------
src/interp/i-toplev.boot | 4 +--
2 files changed, 34 insertions(+), 27 deletions(-)
diff --git a/src/interp/g-timer.boot b/src/interp/g-timer.boot
index cb373c43e..51d0846a7 100644
--- a/src/interp/g-timer.boot
+++ b/src/interp/g-timer.boot
@@ -34,18 +34,20 @@
--% Code instrumentation facilities
-- These functions can be used with arbitrary lists of
-- named stats (listofnames) grouped in classes (listofclasses)
--- and with measurement types (property, classproperty).
+-- and with measurement types (property).
makeLongStatStringByProperty _
- (listofnames, listofclasses, property, classproperty, units, flag) ==
+ (listofnames, listofclasses, property, units, flag) ==
total := 0
str := '""
- otherStatTotal := GET('other, property)
+ if property = 'TimeTotal then statsVec := $statsInfo.0
+ if property = 'SpaceTotal then statsVec := $statsInfo.1
+ otherStatTotal := statsVec.(GET('other, 'index))
insignificantStat := 0
+ classStats := GETZEROVEC(1 + # listofclasses)
for [name,class,:ab] in listofnames repeat
- cl := first LASSOC(class, listofclasses)
- n := GET(name, property)
- PUT(cl, classproperty, n + GET(cl, classproperty))
+ n := statsVec.(GET(name, 'index))
+ classStats.class := classStats.class + n
total := total + n
name = 'other or flag ~= 'long => 'iterate
if significantStat? n then
@@ -56,7 +58,7 @@ makeLongStatStringByProperty _
str := makeStatString(str, otherStatTotal + insignificantStat, 'other, flag)
else
for [class,name,:ab] in listofclasses repeat
- n := GET(name, classproperty)
+ n := classStats.class
str := makeStatString(str, n, ab, flag)
total := STRCONC(normalizeStatAndStringify total,'" ", units)
str = '"" => total
@@ -141,34 +143,41 @@ DEFPARAMETER($interpreterTimedClasses, '(
( 4 reclaim . GC) _
))
-initializeTimedNames(listofnames,listofclasses) ==
- for [name,:.] in listofnames repeat
- PUT(name, 'TimeTotal, 0.0)
- PUT(name, 'SpaceTotal, 0)
- for [.,name,:.] in listofclasses repeat
- PUT( name, 'ClassTimeTotal, 0.0)
- PUT( name, 'ClassSpaceTotal, 0)
+-- $statsInfo contains stats numbers. It is a vector,
+-- $statsInfo.0 is for TimeTotal, $statsInfo.1 is for SpaceTotal.
+DEFVAR($statsInfo)
+
+initializeTimedNames() ==
+ len := # $interpreterTimedNames
+ $statsInfo := VECTOR(GETZEROVEC len, GETZEROVEC len)
+ for [name, :.] in $interpreterTimedNames for i in 0.. repeat
+ PUT(name, 'index, i)
+ initializeTimedStack()
+
+initializeTimedStack() ==
$timedNameStack := '(other)
computeElapsedTime()
computeElapsedSpace()
- PUT('gc, 'TimeTotal, 0.0)
- PUT('gc, 'SpaceTotal, 0)
NIL
updateTimedName name ==
- count := (GET(name, 'TimeTotal) or 0) + computeElapsedTime()
- PUT(name, 'TimeTotal, count)
- count := (GET(name, 'SpaceTotal) or 0) + computeElapsedSpace()
- PUT(name, 'SpaceTotal, count)
+ i := GET(name, 'index)
+ timeVec := $statsInfo.0
+ spaceVec := $statsInfo.1
+ [time, gcTime] := computeElapsedTime()
+ timeVec.i := timeVec.i + time
+ i2 := GET('gc, 'index)
+ timeVec.i2 := timeVec.i2 + gcTime
+ spaceVec.i := spaceVec.i + computeElapsedSpace()
makeLongTimeString(listofnames,listofclasses) ==
makeLongStatStringByProperty(listofnames, listofclasses, _
- 'TimeTotal, 'ClassTimeTotal, _
+ 'TimeTotal, _
'"sec", $printTimeIfTrue)
makeLongSpaceString(listofnames,listofclasses) ==
makeLongStatStringByProperty(listofnames, listofclasses, _
- 'SpaceTotal, 'ClassSpaceTotal, _
+ 'SpaceTotal, _
'"bytes", $printStorageIfTrue)
DEFPARAMETER($inverseTimerTicksPerSecond, 1.0/$timerTicksPerSecond)
@@ -179,11 +188,9 @@ computeElapsedTime() ==
gcDelta := currentGCTime - $oldElapsedGCTime
elapsedSeconds:= $inverseTimerTicksPerSecond *
(currentTime-$oldElapsedTime-gcDelta)
- PUT('gc, 'TimeTotal, GET('gc, 'TimeTotal) +
- $inverseTimerTicksPerSecond*gcDelta)
$oldElapsedTime := currentTime
$oldElapsedGCTime := currentGCTime
- elapsedSeconds
+ [elapsedSeconds, $inverseTimerTicksPerSecond * gcDelta]
computeElapsedSpace() ==
currentElapsedSpace := HEAPELAPSED()
diff --git a/src/interp/i-toplev.boot b/src/interp/i-toplev.boot
index 744bc703e..de9a472d3 100644
--- a/src/interp/i-toplev.boot
+++ b/src/interp/i-toplev.boot
@@ -69,7 +69,7 @@ interpsysInitialization(display_messages) ==
interpOpen(display_messages)
createInitializers()
if $displayStartMsgs then sayKeyedMsg("S2IZ0053",['"interpreter"])
- initializeTimedNames($interpreterTimedNames,$interpreterTimedClasses)
+ initializeTimedNames()
$InteractiveFrame := makeInitialModemapFrame()
initializeSystemCommands()
initializeInterpreterFrameRing()
@@ -128,7 +128,7 @@ DEFPARAMETER($inRetract, nil)
processInteractive(form, posnForm) ==
$timedNameStack : local := NIL
- initializeTimedNames($interpreterTimedNames,$interpreterTimedClasses);
+ initializeTimedStack()
finally(
object := processInteractive0(form, posnForm),
while $timedNameStack repeat stopTimingProcess peekTimedName())