Skip to content

Conversation

@neonene
Copy link
Contributor

@neoneneneonene commented Jun 27, 2024

Reference implementation of the following C-API functinons:

  • PyType_GetBaseByToken()
  • PyType_GetToken()

Discussion: https://discuss.python.org/t/55598


📚 Documentation preview 📚: https://cpython-previews--121079.org.readthedocs.build/

@neonene

This comment was marked as outdated.

@neonene
Copy link
ContributorAuthor

The tp_bases can be used in a fallback implementation. I checked the overhead, adding a repeat function temporarily (100972d):

fromtimeitimporttimeitsetup=f"""if 1: import _testcapi A = _testcapi.create_type_with_token("_testcapi.A", 0) tokenA = _testcapi.get_tp_token(A) class B(A): pass class C(B): pass class D(C): pass class E(D): pass getbase = _testcapi.repeat_getbasebytoken"""c_repeat=10# py_repeat = timeit default (1000000)mro=timeit(s1:=f'getbase(C, tokenA, {c_repeat}, True)', setup) bases=timeit(s2:=f'getbase(C, tokenA, {c_repeat}, False)', setup) print(s1, mro) print(s2, bases, bases/mro)

Win non-debug: (the higher, the slower)

find A
from
starts
with
run once
in C
repeat 10
in C
mroclass A1.001.00
basesclass A1.00x1.00x
mroclass B1.00x1.05x
basesclass B1.01x1.14x
mroclass C1.01x1.10x
basesclass C1.04x1.40x
mroclass E1.02x1.16x
basesclass E1.08x1.50x

@neoneneneonene changed the title Introduce PyType_GetBaseByToken function and friendsIntroduce PyType_GetBaseByToken functionJul 3, 2024
This will keep the slowdown by up to 2% on the `telco` benchmark (PGO). Unlike the `PyDecContextObject`, extending the `PyDecObject` struct seems to affect only binary ops and seems to be a waste of memory.
Faster than the upstream by up to 2% on the `telco` benchmarks (PGO/non-PGO). Based on the GetBaseByToken() optimization by ac82d36.
Keeps the performance unchanged even if the private function is not inlined (i.e. not trained well on PGO).
PyType_GetBaseByToken() fails to inline the wrapped ptivate function, whose overhead appears to be not ignorable.
This cleanup can cause a slowdown by 10% on the `telco` benchmark for some reason.
This version sets the *result to NULL at the end to reduce the overhead of double memory acces when returning true. Under verification.
Copy link
Member

@encukouencukou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good. Do you want to clear the draft bit, and file an issue?

If there are performance more tweaks to make, they can go in a follow-up PR.

PyErr_Format(PyExc_TypeError, "expected a ctypes type, got '%N'", type);
returnNULL;
}
exercise_get_base_by_token(PyCType_Type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remove the exercise from this PR?
Hopefully the training will get better as PyType_GetBaseByToken is used more; if not, we can adjust it in a future PR.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll post a new PR. It may be better to have a dedicated branch when the result argument is NULL.

@neoneneneonene changed the title Introduce PyType_GetBaseByToken functiongh-124153: Introduce PyType_GetBaseByToken function (PoC)Sep 17, 2024
@neoneneneonene closed this Sep 20, 2024
@neoneneneonene deleted the bytoken branch September 20, 2024 03:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@neonene@encukou@erlend-aasland