GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — gh-126868: Add freelist for compact int objects by eendebakpt · Pull Request #126865 · python/cpython Conversation
|
|
I'm running this PR over pyperformance on our benchmarking hardware. It will take ~3 hours. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Actually, scratch that -- I'll wait until the tests are passing here. That's required for PGO builds. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Tests are passing now, but I disabled returning objects to the freelist at a couple of places. Changing |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
What happens exactly when you change these lines: PyStackRef_CLOSE_SPECIALIZED(left, (destructor)PyObject_Free); // needs to be converted to freelist to ? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@markshannon When I change the lines several tests related to refleaks in the CI are failing. For example test_no_memleak, which can be reproduced from the command line with: The output should be |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
The "leaks" are due to the freelist itself. They are a sign the freelist is working :).
Can you please convert all to _PyLong_ExactDealloc and apply the suggestion below, and tell me how many allocations this removes?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
@eendebakpt sorry I pushed to your branch as I'm really eager to get benchmark results on this :). |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
On my machine using the benchmark script provided above (release build, no PGO, no LTO): |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
|
|
||
| if (PyLong_CheckExact(self)) { | ||
| if (_PyLong_IsCompact((PyLongObject *)self)) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
@Fidget-Spinner The _PyLong_IsCompact check has already been done in this method, can we move this into the if (pylong && _PyLong_IsCompact(pylong)) part?
Also, can we remove the pylong && part? I think pylong can never be NULL. (PyLong_CheckExact assumes the pointer is not NULL I think)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ok that sounds good
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Results:
This is a great result! Congrats and great work @eendebakpt ! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, are compact integers allowed to be signed or not? (you mentioned that we only focus on single digit numbers but the C API considers compact objects as being an implementation detail IIRC). If not, how hard would it be to make them support free lists? (I don't have much knowledge in free lists; for instance it's a mystery to me for how the free list grows)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| #include "pycore_pyerrors.h" // _PyErr_GetRaisedException() | ||
| #include "pycore_pystate.h" // _PyInterpreterState_GET() | ||
| #include "pycore_range.h" // _PyRangeIterObject | ||
| #include "pycore_long.h" // void _PyLong_ExactDealloc(PyLongObject *op); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Can we align the // (on mobile it seems 1 char off)?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| 0, /* tp_alloc */ | ||
| long_new, /* tp_new */ | ||
| PyObject_Free, /* tp_free */ | ||
| (freefunc)PyObject_Free, /* tp_free */ |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Can we align the .tp_free comment? (maybe tabs and spaces are mixed, hence that's why I see them unaligned on monile). Also, is the cast necessary to avoid UBSan failures? If not, you can just use .tp_free = ... to emphasize the semantic
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| * we accidentally decref small Ints out of existence. Instead, | ||
| * since small Ints are immortal, re-set the reference count. | ||
| */ |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| * we accidentally decref small Ints out of existence. Instead, | |
| * since small Ints are immortal, re-set the reference count. | |
| */ | |
| * we accidentally decref small Ints out of existence. Instead, | |
| * since small Ints are immortal, re-set the reference count. | |
| */ |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| #include "pycore_bitutils.h" // _Py_popcount32() | ||
| #include "pycore_initconfig.h" // _PyStatus_OK() | ||
| #include "pycore_call.h" // _PyObject_MakeTpCall | ||
| #include "pycore_freelist.h" // _Py_FREELIST_FREE(), _Py_FREELIST_POP() |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Comment alignment.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| /* other API */ | ||
|
|
||
| PyAPI_FUNC(void) _PyLong_ExactDealloc(PyObject *self); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Do you need it to be exported like that or could you live with a simple extern? If not, can you explain which file needs this export?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
It's needed by the JIT on Windows, as it's used in bytecodes.c. This is a pretty common pattern in the internal C API unfortunately
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
For semantic purposes, would it be better to have a macro named differently? (it would be a simple alias but it could help semantics and reviewers)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| { | ||
| assert(PyLong_CheckExact(op)); | ||
| _Py_DECREF_SPECIALIZED((PyObject *)op, (destructor)PyObject_Free); | ||
| _Py_DECREF_SPECIALIZED((PyObject *)op, (destructor) _PyLong_ExactDealloc); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| _Py_DECREF_SPECIALIZED((PyObject *)op, (destructor) _PyLong_ExactDealloc); | |
| _Py_DECREF_SPECIALIZED((PyObject *)op, (destructor)_PyLong_ExactDealloc); |
I'm also not sure whether you need the cast. If you need the cast, I'd suggest changing the signature of the drstructor itself.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I assume you mean the small int checks in |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
…e-126868.yOoHSY.rst
|
I have made the requested changes; please review again |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Thanks for making the requested changes! @markshannon: please review the changes made to this pull request. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this. The code looks good now.
The speedup may not be as large as initially claimed due to addition checks for small integers, but it is a real speedup and should be further improved by #127620
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
It seems likely the thread sanitizer failure is not caused by this PR, but this PR does expose it. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
TSan failure is addressed in #127880. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
The TSan failure is fixed in main now, if you want to merge main back into the PR. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.