cpython: 59b91b4e9506 (original) (raw)

Mercurial > cpython

changeset 105047:59b91b4e9506

Issue #28618: Make hot functions using __attribute__((hot)) When Python is not compiled with PGO, the performance of Python on call_simple and call_method microbenchmarks depend highly on the code placement. In the worst case, the performance slowdown can be up to 70%. The GCC __attribute__((hot)) attribute helps to keep hot code close to reduce the risk of such major slowdown. This attribute is ignored when Python is compiled with PGO. The following functions are considered as hot according to statistics collected by perf record/perf report: * _PyEval_EvalFrameDefault() * call_function() * _PyFunction_FastCall() * PyFrame_New() * frame_dealloc() * PyErr_Occurred() [#28618]

Victor Stinner victor.stinner@gmail.com
date Fri, 11 Nov 2016 02:13:35 +0100
parents c2c72616c9f1
children 5d1067e89717
files Include/pyport.h Objects/frameobject.c Python/ceval.c Python/errors.c
diffstat 4 files changed, 31 insertions(+), 8 deletions(-)[+] [-] Include/pyport.h 27 Objects/frameobject.c 4 Python/ceval.c 6 Python/errors.c 2

line wrap: on

line diff

--- a/Include/pyport.h +++ b/Include/pyport.h @@ -490,13 +490,36 @@ extern "C" {

*/ -#if defined(GNUC) && ((GNUC >= 4) || [](#l1.7)

+#if defined(GNUC) [](#l1.9)

#define Py_DEPRECATED(VERSION_UNUSED) attribute((deprecated)) #else #define Py_DEPRECATED(VERSION_UNUSED) #endif + +/* Py_HOT_FUNCTION

+#define _Py_HOT_FUNCTION attribute((hot)) +#else +#define _Py_HOT_FUNCTION +#endif + /************************************************************************** Prototypes that are missing from the standard include files on some systems (and possibly only some versions of such systems.)

--- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -409,7 +409,7 @@ static int numfree = 0; /* numbe /* max value for numfree */ #define PyFrame_MAXFREELIST 200 -static void +static void _Py_HOT_FUNCTION frame_dealloc(PyFrameObject *f) { PyObject **p, **valuestack; @@ -605,7 +605,7 @@ int _PyFrame_Init() return 1; } -PyFrameObject +PyFrameObject _Py_HOT_FUNCTION PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals) {

--- a/Python/ceval.c +++ b/Python/ceval.c @@ -718,7 +718,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int return tstate->interp->eval_frame(f, throwflag); } -PyObject +PyObject _Py_HOT_FUNCTION _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) { #ifdef DXPAIRS @@ -4771,7 +4771,7 @@ if (tstate->use_tracing && tstate->c_pro x = call; [](#l3.13) } -static PyObject +static PyObject _Py_HOT_FUNCTION call_function(PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames) { PyObject **pfunc = (*pp_stack) - oparg - 1; @@ -4844,7 +4844,7 @@ call_function(PyObject **pp_stack, Py_s done before evaluating the frame. / -static PyObject +static PyObject _Py_HOT_FUNCTION _PyFunction_FastCall(PyCodeObject *co, PyObject **args, Py_ssize_t nargs, PyObject *globals) {

--- a/Python/errors.c +++ b/Python/errors.c @@ -158,7 +158,7 @@ PyErr_SetString(PyObject *exception, con } -PyObject +PyObject _Py_HOT_FUNCTION PyErr_Occurred(void) { PyThreadState *tstate = PyThreadState_GET();