DragomanStats.mesa
Last Edited by: Sweet, March 4, 1985 4:29:04 pm PST
Bertrand Serlet August 5, 1985 1:02:01 pm PDT
DIRECTORY
DragomanOpDebug,
DragomanPrivate,
DragomanRefTab,
AMBridge,
AMTypes,
Basics,
BasicTime,
Convert,
IO,
ListerUtils,
PrincOps,
PrintTV,
Rope;
DragomanStats:
CEDAR PROGRAM
IMPORTS DragomanRefTab, DragomanOpDebug, AMBridge, BasicTime, Convert, IO, PrintTV
EXPORTS DragomanPrivate =
BEGIN
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
Byte: TYPE = Basics.Byte;
Machine: TYPE = DragomanPrivate.Machine;
PrintByColumns:
PUBLIC
PROC [
os: STREAM,
PrintOne: PROC [os: STREAM, item: CARDINAL, lastOnLine: BOOL],
firstItem, nItems, nColumns, spaceBetween: CARDINAL] = {
i, j, nc: CARDINAL;
delta: CARDINAL ← (nItems + nColumns - 1) / nColumns;
last: BOOL;
FOR i
IN [0..delta)
DO
nc ← 0;
last ← FALSE;
FOR j ← i, j + delta
WHILE ~last
AND j < nItems
DO
nc ← nc + 1;
last ← nc = nColumns;
PrintOne[os, firstItem + j, last];
IF ~last THEN THROUGH [0..spaceBetween] DO os.PutChar[' ]; ENDLOOP;
ENDLOOP;
os.PutChar['\n];
ENDLOOP;
};
Sort:
PUBLIC
PROC [
a: LONG DESCRIPTOR FOR ARRAY OF REF,
After: PROC [REF, REF] RETURNS [BOOL]] = TRUSTED {
TreeSort3, -1's to fake 1 origin arrays.
n: CARDINAL = LENGTH[a];
i: CARDINAL;
temp: REF ANY;
SiftUp:
PROC [l, u:
CARDINAL] =
TRUSTED {
s: CARDINAL;
key: REF ANY ← a[l-1];
DO
s ← l*2;
IF s > u THEN EXIT;
IF s < u AND After[a[s+1-1], a[s-1]] THEN s ← s+1;
IF After[key, a[s-1]] THEN EXIT;
a[l-1] ← a[s-1];
l ← s;
ENDLOOP;
a[l-1] ← key};
FOR i DECREASING IN [2..n/2] DO SiftUp[i, n]; ENDLOOP;
FOR i
DECREASING
IN [2..n]
DO
SiftUp[1, i];
temp ← a[1-1];
a[1-1] ← a[i-1];
a[i-1] ← temp;
ENDLOOP;
};
PrintOpCounts:
PUBLIC
PROC [os:
STREAM, m: DragomanPrivate.Machine] =
TRUSTED {
OpItemRec: TYPE = RECORD [op: Byte, count: INT, cumPct: REAL];
OpItemSeq: TYPE = RECORD [SEQUENCE n: CARDINAL OF REF OpItemRec];
oseq: REF OpItemSeq ← NIL;
total: INT← 0;
rTotal: REAL;
nonZ: CARDINAL ← 0;
oc: REF ARRAY Byte OF INT = m.opCount;
opData: ListerUtils.OpCodeArray ← DragomanOpDebug.OpData[];
SmallerCount:
PROC [i1, i2:
REF OpItemRec]
RETURNS [
BOOL] =
TRUSTED {
RETURN [i1.count < i2.count]};
PrintOpItem:
PROC [os:
STREAM, item:
CARDINAL, lastOnLine:
BOOL] =
TRUSTED {
op: Byte = oseq[item].op;
count: INT = oseq[item].count;
opName: ROPE = opData[op].name;
os.PutF["%9g %5g %5g %-6g",
[integer[count]],
[rope[Convert.RopeFromReal[(oseq[item].count/rTotal)*100, 3]]],
[rope[Convert.RopeFromReal[oseq[item].cumPct, 3]]],
[rope[opName]]]};
FOR i:
CARDINAL
IN Byte
DO
IF oc[i] # 0
THEN {
nonZ ← nonZ + 1;
total ← total + oc[i]};
ENDLOOP;
IF nonZ = 0 THEN RETURN;
rTotal ← total;
total ← 0;
oseq ← NEW [OpItemSeq[nonZ]];
nonZ ← 0;
FOR i:
CARDINAL
IN Byte
DO
IF oc[i] # 0
THEN {
oseq[nonZ] ← NEW [OpItemRec ← [op: i, count: oc[i], cumPct: NULL]];
nonZ ← nonZ + 1};
ENDLOOP;
Sort[a: LOOPHOLE[DESCRIPTOR[oseq]], After: LOOPHOLE[SmallerCount]];
FOR i:
CARDINAL
IN [0..nonZ)
DO
count: INT = oseq[i].count;
total ← total + count;
oseq[i].cumPct ← (total / rTotal) * 100;
ENDLOOP;
os.PutF[
" %g outward calls\n", IO.int[m.outCalls]];
PrintByColumns[
os: os, PrintOne: PrintOpItem, firstItem: 0, nItems: nonZ, nColumns: 2, spaceBetween: 0];
};
PrintProcCounts:
PUBLIC
PROC [os:
STREAM, m: Machine] =
TRUSTED {
lc: DragomanRefTab.Ref;
LinkItemRec: TYPE = RECORD [link: PrincOps.ControlLink, count: LONG CARDINAL, time: LONG CARDINAL];
LinkItemSeq: TYPE = RECORD [SEQUENCE n: CARDINAL OF REF LinkItemRec];
ShortOctal:
PROC [n:
CARDINAL]
RETURNS [
IO.Value] =
TRUSTED {
RETURN [[rope[Convert.RopeFromInt[n, 8, n>7]]]]};
SmallerCount:
PROC [i1, i2:
REF LinkItemRec]
RETURNS [
BOOL] =
TRUSTED {
RETURN [i1.time < i2.time]};
lseq: REF LinkItemSeq ← NIL;
n: CARDINAL ← 0;
CountItems: DragomanRefTab.EachPairAction = TRUSTED {IF val.lCount#0 AND val.time>=1000 THEN n ← n+1; RETURN[FALSE]};
InsertItem: DragomanRefTab.EachPairAction =
TRUSTED {
IF val.lCount = 0 OR val.time<1000 THEN RETURN[FALSE];
lseq[n] ← NEW[LinkItemRec ← [link: key.link, count: val.lCount, time: val.time]];
n ← n+1; RETURN[FALSE]};
TRUSTED {lc ← LOOPHOLE[m.xferData]};
IF lc =
NIL
THEN {
os.PutRope["Not remembering Xfers"];
RETURN};
[] ← DragomanRefTab.Pairs[lc, CountItems];
lseq ← NEW [LinkItemSeq[n]];
n ← 0;
[] ← DragomanRefTab.Pairs[lc, InsertItem];
Sort[a: LOOPHOLE[DESCRIPTOR[lseq]], After: LOOPHOLE[SmallerCount]];
os.PutF["\n 10 time consuming outward calls from interpreter (%g total)\t\t[ms, #, gfi, name]\n", [integer[m.outCalls]]];
FOR i:
CARDINAL
IN [0 .. MIN[10, n])
DO
item: REF LinkItemRec = lseq[i];
tv: AMTypes.TV ← AMBridge.TVForProc[LOOPHOLE[item.link]];
os.PutF["%8g\t%8g\t%4g\t",
[cardinal[BasicTime.PulsesToMicroseconds[item.time]/1000]],
[cardinal[item.count]],
[integer[item.link.gfi]]];
PrintTV.Print[tv, os];
os.PutF["\n"];
ENDLOOP;
os.PutRope["~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"];
};
END.