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())

Reply via email to