Repository navigation
Cleanup object.h header #83723
Copy link
Copy link
Closed
Labels
Description
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = <Date 2020-07-08.08:30:06.202>
created_at = <Date 2020-02-03.15:42:01.002>
labels = ['expert-C-API', '3.9']
title = 'Cleanup object.h header'
updated_at = <Date 2020-07-11.17:52:28.975>
user = 'https://github.com/vstinner'bugs.python.org fields:
activity = <Date 2020-07-11.17:52:28.975>
actor = 'Jim.Jewett'
assignee = 'none'
closed = True
closed_date = <Date 2020-07-08.08:30:06.202>
closer = 'vstinner'
components = ['C API']
creation = <Date 2020-02-03.15:42:01.002>
creator = 'vstinner'
dependencies = []
files = ['49303']
hgrepos = []
issue_num = 39542
keywords = ['patch']
message_count = 28.0
messages = ['361305', '361307', '361311', '361384', '361422', '361425', '361429', '361431', '361432', '361442', '361505', '372962', '372983', '372984', '372993', '372994', '372995', '373028', '373230', '373231', '373234', '373235', '373236', '373237', '373239', '373282', '373288', '373530']
nosy_count = 8.0
nosy_names = ['rhettinger', 'pitrou', 'vstinner', 'petr.viktorin', 'skrah', 'lukasz.langa', 'Jim.Jewett', 'serhiy.storchaka']
pr_nums = ['18331', '18332', '18346', '18362', '18363', '18364', '18366', '18368', '18378', '18384']
priority = None
resolution = 'fixed'
stage = 'resolved'
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue39542'
versions = ['Python 3.9']Reactions are currently unavailable
Activity
vstinner commentedon Feb 3, 2020
In bpo-39489, I removed the COUNT_ALLOCS special build. The object.h header can now be cleaned up to simplify the code.
vstinner commentedon Feb 3, 2020
New changeset 4b52416 by Victor Stinner in branch 'master':
bpo-39542: Move object.h debug functions to internal C API (GH-18331)
4b52416
vstinner commentedon Feb 3, 2020
New changeset 49932fe by Victor Stinner in branch 'master':
bpo-39542: Simplify _Py_NewReference() (GH-18332)
49932fe
vstinner commentedon Feb 5, 2020
New changeset 40e547d by Victor Stinner in branch 'master':
bpo-39542: Make _Py_NewReference() opaque in C API (GH-18346)
40e547d
vstinner commentedon Feb 5, 2020
New changeset 0fa4f43 by Victor Stinner in branch 'master':
bpo-39542: Exclude trashcan from the limited C API (GH-18362)
0fa4f43
vstinner commentedon Feb 5, 2020
New changeset f58bd7c by Victor Stinner in branch 'master':
bpo-39542: Make PyObject_INIT() opaque in limited C API (GH-18363)
f58bd7c
vstinner commentedon Feb 5, 2020
New changeset 509dd90 by Victor Stinner in branch 'master':
bpo-39542: Convert PyType_Check() to static inline function (GH-18364)
509dd90
vstinner commentedon Feb 5, 2020
New changeset 0e4e735 by Victor Stinner in branch 'master':
bpo-39542: Define PyTypeObject earlier in object.h (GH-18366)
0e4e735
vstinner commentedon Feb 5, 2020
Ok, object.h looks much better now! I close the issue.
13 remaining items
vstinner commentedon Jul 7, 2020
Raymond:
Raymond gave more context in this email:
https://mail.python.org/archives/list/python-dev@python.org/message/Q3YHYIKNUQH34FDEJRSLUP2MTYELFWY3/
As far as I know, only macOS is impacted by this performance regression (119 nsec => 152 nsec on a microbenchmark). On Windows and Linux, Python is built with LTO and PGO optimizations.
For example, the Python package provided by Fedora 32 is built with GCC 10 using LTO and PGO. Using GCC 10 and LTO, the PyTuple_Check() code is inlined even if PyType_GetFlags() is function call in PyType_HasFeature().
I didn't know that on macOS, LTO was not used. I created bpo-41181 to request to enable LTO on the macOS installer builder, but Ned Deily rejected the issue (read the issue for the rationale).
I dislike comparing performances when LTO and PGO optimizations are not used. LTO enables tons of optimizations and PGO makes benchmark results more reproducible.
One idea is to stop running benchmarks on macOS, and at least only run benchmarks on binaries built with LTO and PGO.
--
Raymond:
I'm not sure the performance changed with this commit. IMHO it's more the commit 45ec5b9: bpo-40170 and #63577.
Background behind this change: see PEP-620 for the overall plan, see bpo-39573 and bpo-40170 to make PyObject and PyTypeObject structures opaque. The idea is to slowly move third party extension modules towards the stable ABI (PEP-384). Internally, CPython continues to access directly structure members.
#63577 was reviewed and approved by another core dev.
The impact of performance of these changes was taken in account, and that's why it was decided to add a new internal _PyType_HasFeature() function.
It wasn't noticed that PyTuple_Check() calls the public PyType_HasFeature() instead of the internal _PyType_HasFeature(). As I wrote, using LTO, the code is inlined anyway, so it's the same thing.
vstinner commentedon Jul 7, 2020
Stefan Krah:
I don't understand the relationship between this issue, Christian Heimes and making reviews mandatory or not.
As I wrote, the commit 45ec5b9 was reviewed and approved by another core dev.
Stefan, please stop personal attack and stay at the technical level.
rhettinger commentedon Jul 7, 2020
Here are two timings for math.dist(). They were run with the production macOS builds from python.org:
The attached screen shot shows that the only change between the two versions is that the subclass check is inlined and fast in 3.8, but is an external function call in 3.9.
---- 3.8 subclass check -----------
movq 8(%r12), %rax
movl $0, 32(%rsp)
testb $4, 171(%rax)
je L779
---- 3.9 subclass check -----------
The C code for math.dist() is unchanged between 3.8 and 3.9. Both use PyTuple_Check().
This isn't unique. Every single PyTuple_Check() is the similarly affected (approx. 225 occurrences). Presumably, this affects other type checks as well.
rhettinger commentedon Jul 7, 2020
Serhiy, do you have any insights to offer?
skrah commentedon Jul 7, 2020
A brief note for Victor that *nothing* was directed against him. On
the contrary, msg372995 was supporting him in case the commit had
actually been unreviewed, which it apparently wasn't. Sorry for
jumping on the bandwagon there.
This one I have some trouble with. It cites PyPy as a bottleneck, but
IIRC Armin Rigo was on record saying that such changes would not help
PyPy, and he would come up with a counter proposal. Has this changed?
It is also a bit unusual that the PEP is in draft status but a lot
of things are already committed.
skrah commentedon Jul 7, 2020
s/PyPy as a bottleneck/the C-API as a bottle neck for PyPy/
rhettinger commentedon Jul 7, 2020
Victor, is there any reason PyType_GetFlags() can't be converted to a macro or an inlined function? That seems like a simple and robust fix that won't get in the way of anything else you're doing.
We shouldn't disregard macOS timings. It is an important platform —dominant in data science, dominant among most of my clients, and dominant among the core developers at the last sprint.
None of the inlining should depend on LTO and PGO. That is fragile and will create hard-to-explain variations between builds (even consecutive builds on the same platform). Third-party extensions, SO and DLL files won't benefit from that. Also, it makes it difficult to individually optimize and analyze a function without a costly rebuild at every step.
serhiy-storchaka commentedon Jul 8, 2020
I do not know the purpose of this issue. The new code does not look cleaner to me, but maybe it is only for me.
But performance regressions should be fixed. We cannot rely on compiler-specific global optimization, which is hard to test and does not work for dynamic linkage (third-party extensions and applications with built-in Python). Even "inline" is just a hint to the compiler and does not guarantee inlining the code.
Raymond's suggestions look reasonable to me.
vstinner commentedon Jul 8, 2020
Since the PEP-620 is still a draft, I created PR 21390 to fix the performance issue.
As I wrote, I didn't expect any impact on performances since I added _PyType_HasFeature() which access directly the structure member. But I was wrong.
This change is not strictly required by my work for now, so I just revert it until the PEP is accepted.
If I reapply the change later, I will take care of ensuring that it's properly optimized in CPython internals (access the member, don't call a function), especially on macOS.
If you want to continue the discussion, please discuss on bpo-40170, since this issue is unrelated.
Stefan Krah:
Raymond:
Serhiy Storchaka:
I explained the rationale in bpo-40170 and PEP-620.
It's not a "cleanup change". Serhiy: we are discussing the commit 45ec5b9 of bpo-40170.
This discussion is happening in the wrong bpo which seems to confuse people. So I close again this issue which is fixed.
jimjjewett commentedon Jul 11, 2020
Raymond, did you replace the screenshot with a later one showing that things are fixed now? The timestamp suggests it went up at the same time as your comment, but what I see in the .png file is that the two are identical other than addresses.