From 18dea7d67d8b263dd8b49e1d44dcb09ca86ad08a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 11 Nov 2016 02:13:35 +0100 Subject: 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() --- Include/pyport.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'Include/pyport.h') diff --git a/Include/pyport.h b/Include/pyport.h index 20f3db7481..b91fc7468a 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -490,13 +490,36 @@ extern "C" { * typedef int T1 Py_DEPRECATED(2.4); * extern int x() Py_DEPRECATED(2.5); */ -#if defined(__GNUC__) && ((__GNUC__ >= 4) || \ - (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) +#if defined(__GNUC__) \ + && ((__GNUC__ >= 4) || (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) #else #define Py_DEPRECATED(VERSION_UNUSED) #endif + +/* Py_HOT_FUNCTION + * The hot attribute on a function is used to inform the compiler that the + * function is a hot spot of the compiled program. The function is optimized + * more aggressively and on many target it is placed into special subsection of + * the text section so all hot functions appears close together improving + * locality. + * + * Usage: + * int Py_HOT_FUNCTION x() { return 3; } + * + * Issue #28618: This attribute must not be abused, otherwise it can have a + * negative effect on performance. Only the functions were Python spend most of + * its time must use it. Use a profiler when running performance benchmark + * suite to find these functions. + */ +#if defined(__GNUC__) \ + && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) +#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.) -- cgit v1.2.1 From 980554ec4d992135f53e5a919047c835b7a68925 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Nov 2016 15:13:40 +0100 Subject: Issue #28618: Mark dict lookup functions as hot It's common to see these functions in the top 3 of "perf report". --- Include/pyport.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Include/pyport.h') diff --git a/Include/pyport.h b/Include/pyport.h index b91fc7468a..f7a16b264b 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -498,7 +498,7 @@ extern "C" { #endif -/* Py_HOT_FUNCTION +/* _Py_HOT_FUNCTION * The hot attribute on a function is used to inform the compiler that the * function is a hot spot of the compiled program. The function is optimized * more aggressively and on many target it is placed into special subsection of @@ -506,7 +506,7 @@ extern "C" { * locality. * * Usage: - * int Py_HOT_FUNCTION x() { return 3; } + * int _Py_HOT_FUNCTION x() { return 3; } * * Issue #28618: This attribute must not be abused, otherwise it can have a * negative effect on performance. Only the functions were Python spend most of -- cgit v1.2.1 From 3106ff9ad570b650a3afee6ebc4adc7430c5eca2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 11 Jan 2017 01:07:03 +0100 Subject: Disable _PyStack_AsTuple() inlining Issue #29234: Inlining _PyStack_AsTuple() into callers increases their stack consumption, Disable inlining to optimize the stack consumption. Add _Py_NO_INLINE: use __attribute__((noinline)) of GCC and Clang. It reduces the stack consumption, bytes per call, before => after: test_python_call: 1040 => 976 (-64 B) test_python_getitem: 976 => 912 (-64 B) test_python_iterator: 1120 => 1056 (-64 B) => total: 3136 => 2944 (- 192 B) --- Include/pyport.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'Include/pyport.h') diff --git a/Include/pyport.h b/Include/pyport.h index def2975d47..03c664f397 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -507,7 +507,7 @@ extern "C" { * locality. * * Usage: - * int _Py_HOT_FUNCTION x() { return 3; } + * int _Py_HOT_FUNCTION x(void) { return 3; } * * Issue #28618: This attribute must not be abused, otherwise it can have a * negative effect on performance. Only the functions were Python spend most of @@ -521,6 +521,19 @@ extern "C" { #define _Py_HOT_FUNCTION #endif +/* _Py_NO_INLINE + * Disable inlining on a function. For example, it helps to reduce the C stack + * consumption. + * + * Usage: + * int _Py_NO_INLINE x(void) { return 3; } + */ +#if defined(__GNUC__) || defined(__clang__) +# define _Py_NO_INLINE __attribute__((noinline)) +#else +# define _Py_NO_INLINE +#endif + /************************************************************************** Prototypes that are missing from the standard include files on some systems (and possibly only some versions of such systems.) -- cgit v1.2.1