[Python-checkins] python/dist/src/Python ceval.c, 2.398, 2.399 pystate.c, 2.30, 2.31 sysmodule.c, 2.123, 2.124

loewis at users.sourceforge.net loewis at users.sourceforge.net
Tue Jun 8 04:17:47 EDT 2004


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29830/Python

Modified Files:
	ceval.c pystate.c sysmodule.c 
Log Message:
Patch #510695: Add TSC profiling for the VM.


Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.398
retrieving revision 2.399
diff -C2 -d -r2.398 -r2.399
*** ceval.c	5 Jun 2004 06:16:22 -0000	2.398
--- ceval.c	8 Jun 2004 08:17:43 -0000	2.399
***************
*** 18,21 ****
--- 18,41 ----
  #include <ctype.h>
  
+ #ifdef WITH_TSC
+ #include <asm/msr.h>
+ 
+ typedef unsigned long long uint64;
+ 
+ void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1, 
+ 	      uint64 loop0, uint64 loop1, uint64 intr0, uint64 intr1)
+ {
+ 	uint64 intr, inst, loop;
+ 	PyThreadState *tstate = PyThreadState_Get();
+ 	if (!tstate->interp->tscdump)
+ 		return;
+ 	intr = intr1 - intr0;
+ 	inst = inst1 - inst0 - intr;
+ 	loop = loop1 - loop0 - intr;
+ 	fprintf(stderr, "opcode=%03d t=%d inst=%06lld loop=%06lld\n",
+ 		opcode, ticked, inst, loop);
+ }
+ #endif
+ 
  /* Turn this on if your compiler chokes on the big switch: */
  /* #define CASE_TOO_BIG 1 */
***************
*** 31,35 ****
--- 51,59 ----
  /* Forward declarations */
  static PyObject *eval_frame(PyFrameObject *);
+ #ifdef WITH_TSC
+ static PyObject *call_function(PyObject ***, int, uint64*, uint64*);
+ #else
  static PyObject *call_function(PyObject ***, int);
+ #endif
  static PyObject *fast_function(PyObject *, PyObject ***, int, int, int);
  static PyObject *do_call(PyObject *, PyObject ***, int, int);
***************
*** 486,489 ****
--- 510,551 ----
  #endif
  
+ #ifdef WITH_TSC
+ /* Use Pentium timestamp counter to mark certain events:
+    inst0 -- beginning of switch statement for opcode dispatch
+    inst1 -- end of switch statement (may be skipped)
+    loop0 -- the top of the mainloop
+    loop1 -- place where control returns again to top of mainloop 
+             (may be skipped)
+    intr1 -- beginning of long interruption
+    intr2 -- end of long interruption
+ 
+    Many opcodes call out to helper C functions.  In some cases, the
+    time in those functions should be counted towards the time for the
+    opcode, but not in all cases.  For example, a CALL_FUNCTION opcode
+    calls another Python function; there's no point in charge all the
+    bytecode executed by the called function to the caller.
+ 
+    It's hard to make a useful judgement statically.  In the presence
+    of operator overloading, it's impossible to tell if a call will
+    execute new Python code or not.
+ 
+    It's a case-by-case judgement.  I'll use intr1 for the following
+    cases:
+ 
+    EXEC_STMT
+    IMPORT_STAR
+    IMPORT_FROM
+    CALL_FUNCTION (and friends)
+ 
+  */
+ 	uint64 inst0, inst1, loop0, loop1, intr0 = 0, intr1 = 0;
+ 	int ticked = 0;
+ 
+ 	rdtscll(inst0);
+ 	rdtscll(inst1);
+ 	rdtscll(loop0);
+ 	rdtscll(loop1);
+ #endif
+ 
  /* Code access macros */
  
***************
*** 644,647 ****
--- 706,726 ----
  
  	for (;;) {
+ #ifdef WITH_TSC
+ 		if (inst1 == 0) {
+ 			/* Almost surely, the opcode executed a break
+ 			   or a continue, preventing inst1 from being set
+ 			   on the way out of the loop.
+ 			*/
+ 			rdtscll(inst1);
+ 			loop1 = inst1;
+ 		}
+ 		dump_tsc(opcode, ticked, inst0, inst1, loop0, loop1,
+ 			 intr0, intr1);
+ 		ticked = 0;
+ 		inst1 = 0;
+ 		intr0 = 0;
+ 		intr1 = 0;
+ 		rdtscll(loop0);
+ #endif
  		assert(stack_pointer >= f->f_valuestack); /* else underflow */
  		assert(STACK_LEVEL() <= f->f_stacksize);  /* else overflow */
***************
*** 663,666 ****
--- 742,748 ----
  			_Py_Ticker = _Py_CheckInterval;
  			tstate->tick_counter++;
+ #ifdef WITH_TSC
+ 			ticked = 1;
+ #endif
  			if (things_to_do) {
  				if (Py_MakePendingCalls() < 0) {
***************
*** 753,756 ****
--- 835,841 ----
  
  		/* Main switch on opcode */
+ #ifdef WITH_TSC
+ 		rdtscll(inst0);
+ #endif
  
  		switch (opcode) {
***************
*** 1494,1498 ****
--- 1579,1589 ----
  			u = THIRD();
  			STACKADJ(-3);
+ #ifdef WITH_TSC
+ 			rdtscll(intr0);
+ #endif
  			err = exec_statement(f, u, v, w);
+ #ifdef WITH_TSC
+ 			rdtscll(intr1);
+ #endif
  			Py_DECREF(u);
  			Py_DECREF(v);
***************
*** 1856,1860 ****
--- 1947,1957 ----
  				break;
  			}
+ #ifdef WITH_TSC
+ 			rdtscll(intr0);
+ #endif
  			x = PyEval_CallObject(x, w);
+ #ifdef WITH_TSC
+ 			rdtscll(intr1);
+ #endif
  			Py_DECREF(w);
  			SET_TOP(x);
***************
*** 1870,1874 ****
--- 1967,1977 ----
  				break;
  			}
+ #ifdef WITH_TSC
+ 			rdtscll(intr0);
+ #endif
  			err = import_all_from(x, v);
+ #ifdef WITH_TSC
+ 			rdtscll(intr1);
+ #endif
  			PyFrame_LocalsToFast(f, 0);
  			Py_DECREF(v);
***************
*** 1879,1883 ****
--- 1982,1992 ----
  			w = GETITEM(names, oparg);
  			v = TOP();
+ #ifdef WITH_TSC
+ 			rdtscll(intr0);
+ #endif
  			x = import_from(v, w);
+ #ifdef WITH_TSC
+ 			rdtscll(intr1);
+ #endif
  			PUSH(x);
  			if (x != NULL) continue;
***************
*** 1988,1992 ****
--- 2097,2105 ----
  		case CALL_FUNCTION:
  			PCALL(PCALL_ALL);
+ #ifdef WITH_TSC
+ 			x = call_function(&stack_pointer, oparg, &intr0, &intr1);
+ #else
  			x = call_function(&stack_pointer, oparg);
+ #endif
  			PUSH(x);
  			if (x != NULL)
***************
*** 2023,2027 ****
--- 2136,2146 ----
  		    } else
  			    Py_INCREF(func);
+ #ifdef WITH_TSC
+ 		    rdtscll(intr0);
+ #endif
  		    x = ext_do_call(func, &stack_pointer, flags, na, nk);
+ #ifdef WITH_TSC
+ 		    rdtscll(intr1);
+ #endif
  		    Py_DECREF(func);
  
***************
*** 2135,2138 ****
--- 2254,2261 ----
  	    on_error:
  
+ #ifdef WITH_TSC
+ 		rdtscll(inst1);
+ #endif
+ 
  		/* Quickly continue if no error occurred */
  
***************
*** 2144,2150 ****
  					fprintf(stderr,
  						"XXX undetected error\n");
! 				else
  #endif
  					continue; /* Normal, fast path */
  			}
  			why = WHY_EXCEPTION;
--- 2267,2279 ----
  					fprintf(stderr,
  						"XXX undetected error\n");
! 				else {
! #endif
! #ifdef WITH_TSC
! 					rdtscll(loop1);
  #endif
  					continue; /* Normal, fast path */
+ #ifdef CHECKEXC
+ 				}
+ #endif
  			}
  			why = WHY_EXCEPTION;
***************
*** 2261,2264 ****
--- 2390,2396 ----
  		if (why != WHY_NOT)
  			break;
+ #ifdef WITH_TSC
+ 		rdtscll(loop1);
+ #endif
  
  	} /* main loop */
***************
*** 3332,3336 ****
  
  static PyObject *
! call_function(PyObject ***pp_stack, int oparg)
  {
  	int na = oparg & 0xff;
--- 3464,3472 ----
  
  static PyObject *
! call_function(PyObject ***pp_stack, int oparg
! #ifdef WITH_TSC
! 		, uint64* pintr0, uint64* pintr1
! #endif
! 		)
  {
  	int na = oparg & 0xff;
***************
*** 3375,3379 ****
--- 3511,3521 ----
  			callargs = load_args(pp_stack, na);
  			BEGIN_C_TRACE
+ #ifdef WITH_TSC
+ 			rdtscll(*pintr0);
+ #endif
  			x = PyCFunction_Call(func, callargs, NULL);
+ #ifdef WITH_TSC
+ 			rdtscll(*pintr1);
+ #endif
  			END_C_TRACE
  			Py_XDECREF(callargs);
***************
*** 3394,3401 ****
--- 3536,3549 ----
  		} else
  			Py_INCREF(func);
+ #ifdef WITH_TSC
+ 		rdtscll(*pintr0);
+ #endif
  		if (PyFunction_Check(func))
  			x = fast_function(func, pp_stack, n, na, nk);
  		else
  			x = do_call(func, pp_stack, na, nk);
+ #ifdef WITH_TSC
+ 		rdtscll(*pintr1);
+ #endif
  		Py_DECREF(func);
  	}

Index: pystate.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v
retrieving revision 2.30
retrieving revision 2.31
diff -C2 -d -r2.30 -r2.31
*** pystate.c	24 Mar 2004 22:22:12 -0000	2.30
--- pystate.c	8 Jun 2004 08:17:44 -0000	2.31
***************
*** 60,63 ****
--- 60,66 ----
  #endif
  #endif
+ #ifdef WITH_TSC
+ 		interp->tscdump = 0;
+ #endif
  
  		HEAD_LOCK();

Index: sysmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v
retrieving revision 2.123
retrieving revision 2.124
diff -C2 -d -r2.123 -r2.124
*** sysmodule.c	24 Mar 2004 22:22:12 -0000	2.123
--- sysmodule.c	8 Jun 2004 08:17:44 -0000	2.124
***************
*** 443,446 ****
--- 443,473 ----
  );
  
+ #ifdef WITH_TSC
+ static PyObject *
+ sys_settscdump(PyObject *self, PyObject *args)
+ {
+ 	int bool;
+ 	PyThreadState *tstate = PyThreadState_Get();
+ 
+ 	if (!PyArg_ParseTuple(args, "i:settscdump", &bool))
+ 		return NULL;
+ 	if (bool)
+ 		tstate->interp->tscdump = 1;
+ 	else
+ 		tstate->interp->tscdump = 0;
+ 	Py_INCREF(Py_None);
+ 	return Py_None;
+ 	
+ }
+ 
+ PyDoc_STRVAR(settscdump_doc, 
+ "settscdump(bool)\n\
+ \n\
+ If true, tell the Python interpreter to dump VM measurements to\n\
+ stderr.  If false, turn off dump.  The measurements are based on the\n\
+ Pentium time-stamp counter."
+ ); 
+ #endif TSC
+ 
  static PyObject *
  sys_setrecursionlimit(PyObject *self, PyObject *args)
***************
*** 744,747 ****
--- 771,777 ----
  	{"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS,
  	 setrecursionlimit_doc},
+ #ifdef WITH_TSC
+ 	{"settscdump", sys_settscdump, METH_VARARGS, settscdump_doc},
+ #endif
  	{"settrace",	sys_settrace, METH_O, settrace_doc},
  	{"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc},




More information about the Python-checkins mailing list