add a global tick register to the interpreter?
(Please forgive me if this belongs on python-dev.) When measuring the performance of a Python or Python program, it is often required to keep precise count of interpreter tics and periodic checks. There is no way to to this reliably, except modify ceval.c and rebuild Python. I think facilities for performance measures should be available. It should not be neccesary edit ceval.c and rebuild Python just to measure how Python itself or a Python program performs. I am therefore proposing this change to ceval.c: New global declarations: /* tick and check counters */ volatile PY_LONG_LONG _Py_Interpreter_Ticks = 0; volatile PY_LONG_LONG _Py_Interpreter_Checks = 0; The big infinite loop in PyEval_EvalFrameEx becomes for (;;Py_Interpreter_Ticks++) { #ifdef WITH_TSC if (inst1 == 0) { with periodic checks like this: if (--_Py_Ticker < 0) { _Py_Interpreter_Checks++; The reason for this change is that _Py_Ticker cannot be used for performance measures, as the variable can be set to zero during check intervals themselves or asynchronously from callbacks/signals. The variables _Py_Interpreter_Checks and Py_Interpreter_Ticks would be available to extension developers using the declaration: extern const volatile PY_LONG_LONG _Py_Interpreter_Ticks; extern const volatile PY_LONG_LONG _Py_Interpreter_Checks; #define PyEval_GetInterpreterTicks (_Py_Interpreter_Ticks) /* or an inline function */ #define PyEval_GetInterpreterChecks (_Py_Interpreter_Checks) (A 'const volatile' is a C variable that cannot be written to, but can suddenly be changed from the environment.) From the Python side we would have: sys.tickcounter # or sys.getinterpreterticks? sys.checkcounter The counters must be 64 bit because of the speed of Python. On my computer I measure close to 3 million interpreter ticks per second. That would exhaust a (signed) 32 bit counter in 11 minutes. A signed 64 bit counter could go on for 24 thousand years. (This is not covered by Guido's moratorium as it is an implementation and library issue.) Regards, Sturla Molden
Sturla Molden <sturla@...> writes:
When measuring the performance of a Python or Python program, it is often required to keep precise count of interpreter tics and periodic checks.
Well... interpreter ticks only measures the number of opcodes executed, not the number of seconds elapsed. It's not a reliable performance measure at all, unless you want to measure ticking itself.
Antoine Pitrou skrev:
Well... interpreter ticks only measures the number of opcodes executed, not the number of seconds elapsed. It's not a reliable performance measure at all, unless you want to measure ticking itself.
I did not mention that: In Windows we get precise timings using QueryPerformanceCounter and QueryPerformanceFrequency. On Linux it would be uclock and UCLOCKS_PER_SEC. An C extension using the proposed API would have to call these functions itself. The proposed registers are thus not for timing, but for measuring how many times the interpreter has ticked and tocked. Or we could make it easier to write cross-platform extensions and have a function that retreives these numbers together with a high-precision timing in microseconds: int PyEval_GetPerformanceStats( PY_LONG_LONG *ticks, PY_LONG_LONG *checks, double *us); Sturla Molden
Sturla Molden <sturla@...> writes:
In Windows we get precise timings using QueryPerformanceCounter and QueryPerformanceFrequency. On Linux it would be uclock and UCLOCKS_PER_SEC. An C extension using the proposed API would have to call these functions itself. The proposed registers are thus not for timing, but for measuring how many times the interpreter has ticked and tocked.
Well, given I plan to propose a removal of the whole "ticking" scheme (see the "newgil" branch in the sandbox if you are curious), I am personally not terribly interested in giving access to the current counters :-) However, a cross-platform API for accessing high-resolution timers could be nice. Regards Antoine.
participants (2)
-
Antoine Pitrou
-
Sturla Molden