Attachment "tebcTiming.patch" to
ticket [1828178fff]
added by
msofer
2007-11-08 17:30:06.
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.341
diff -u -r1.341 tclExecute.c
--- generic/tclExecute.c 8 Nov 2007 07:10:43 -0000 1.341
+++ generic/tclExecute.c 8 Nov 2007 10:24:35 -0000
@@ -9,6 +9,7 @@
* Copyright (c) 2002-2005 by Miguel Sofer.
* Copyright (c) 2005-2007 by Donal K. Fellows.
* Copyright (c) 2007 Daniel A. Steffen <[email protected]>
+ * Copyright (c) 2007 George Peter Staplin.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -23,6 +24,25 @@
#include <math.h>
#include <float.h>
+#define TCL_VM_TIME_TABLE 1
+
+#ifdef TCL_VM_TIME_TABLE
+
+#ifdef TCL_WIDE_CLICKS
+#define GetClicks(foo) (foo = TclpGetWideClicks())
+#elif 1
+/* Taken from linux's asm-x86_64/msr.h rdtscll */
+#define GetClicks(foo) do { \
+ uint32_t __a,__d; \
+ asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
+ (foo) = ((uint64_t)__a) | (((uint64_t)__d)<<32); \
+ } while(0)
+#else
+#define GetClicks(foo) (foo = TclpGetClicks())
+#endif
+#endif
+
+
/*
* Hack to determine whether we may expect IEEE floating point. The hack is
* formally incorrect in that non-IEEE platforms might have the same precision
@@ -1498,6 +1518,38 @@
Tcl_SetBignumObj(valuePtr, &value);
return TCL_OK;
}
+
+#ifdef TCL_VM_TIME_TABLE
+
+static int timeTableReady = 0;
+static Tcl_WideInt childClicks = 0;
+static Tcl_WideInt biasClicks = 0;
+static struct {
+ Tcl_WideInt instCount;
+ Tcl_WideInt instTotalTime;
+} timeTable[LAST_INST_OPCODE + 1];
+
+static void
+DumpTimeTable(void) {
+ int i;
+ FILE *fp;
+
+ fp = fopen("time.log", "a");
+ if (NULL == fp) {
+ perror("fopen");
+ return;
+ }
+
+ for (i = 0; i <= LAST_INST_OPCODE; ++i) {
+ if (timeTable[i].instTotalTime) {
+ fprintf(fp, "%d %lld %lld\n", i, timeTable[i].instTotalTime,
+ timeTable[i].instCount);
+ }
+ }
+ fprintf(fp, "- -\n");
+}
+#endif
+
/*
*----------------------------------------------------------------------
@@ -1529,6 +1581,10 @@
*/
#define iPtr ((Interp *) interp)
+#ifdef TCL_VM_TIME_TABLE
+ int lastInstruction = -1;
+ Tcl_WideInt before = 0, clicks, startClicks = 0;
+#endif
/*
* Constants: variables that do not change during the execution, used
* sporadically.
@@ -1634,6 +1690,26 @@
namespacePtr = iPtr->varFramePtr->nsPtr;
compiledLocals = iPtr->varFramePtr->compiledLocals;
+
+#if TCL_VM_TIME_TABLE
+ if (!timeTableReady) {
+ int i;
+
+ GetClicks(clicks);
+ for (i = 0; i <= LAST_INST_OPCODE; ++i) {
+ timeTable[i].instCount = timeTable[i].instTotalTime = 0;
+ GetClicks(biasClicks);
+ }
+ biasClicks = (biasClicks - clicks)/i;
+ fprintf(stderr, "biasClicks %lld\n", biasClicks);
+
+ timeTableReady = 1;
+ if (atexit(DumpTimeTable))
+ perror("atexit");
+ }
+#endif
+
+
/*
* Loop executing instructions until a "done" instruction, a TCL_RETURN,
* or some error.
@@ -1758,6 +1834,20 @@
}
}
+
+#ifdef TCL_VM_TIME_TABLE
+ GetClicks(clicks);
+ if (before && (-1 != lastInstruction)) {
+ timeTable[lastInstruction].instTotalTime += clicks - before - childClicks;
+ timeTable[lastInstruction].instCount++;
+ } else {
+ startClicks = clicks;
+ }
+ childClicks = 0;
+ before = clicks + biasClicks;
+ lastInstruction = *pc;
+#endif
+
/*
* These two instructions account for 26% of all instructions (according
* to measurements on tclbench by Ben Vitale
@@ -7078,6 +7168,16 @@
}
}
+#ifdef TCL_VM_TIME_TABLE
+ GetClicks(clicks);
+ if (before && (-1 != lastInstruction)) {
+ timeTable[lastInstruction].instTotalTime += clicks - before - childClicks;
+ timeTable[lastInstruction].instCount++;
+ }
+ GetClicks(childClicks);
+ childClicks -= startClicks;
+#endif
+
/*
* Restore the stack to the state it had previous to this bytecode.
*/