Live data from Hacker News

Performance of the Python 3.14 tail-call interpreter

blog.nelhage.com

81–90 of 180 posts

Re: Performance of the Python 3.14 tail-call interpreter

#81

Hello. I'm the author of the PR that landed the tail-calling interpreter in CPython. First, I want to say thank you to Nelson for spending almost a month to get to the root of this issue. Secondly, I want to say I'm extremely embarrassed and sorry that I made such a huge oversight. I, and probably the rest of the CPython team did not expect the compiler we were using for the baseline to have that bug. I posted an apo…

Thank you for doing work that makes python better for millions of people.

Re: Performance of the Python 3.14 tail-call interpreter

#82

Earlier quoted context omitted.

One question arises: does the added code [1] bring any improvement, or does it merely complicate the source? Should it not be removed? [1] https://github.com/python/cpython/pull/128718

That's a fair question. The blog post mentions it brings a 1-5% perf improvement. Which is still significant for CPython. It does not complicate the source because we use a DSL to generate CPython's interpreters. So the only complexity is in autogenerated code, which is usually meant for machine consumption anyways. The other benefit (for us maintainers I guess), is that it compiles way faster and is more debuggable…

There was a plan for a 5x speedup overall looking for funding back in 2022. Then a team with Guido and others involved (and MS backing?) got on the same bandwagon and made some announcements for speeding up CPython a lot.

Several releases in, have we seen even a 2x speedup? Or more like 0.2x at best?

Not trying to dismiss the interpreter changes - more want to know if those speedup plans were even remotely realistic, and if anything close enough to even 1/5 of what was promised will really come out of them...

Re: Performance of the Python 3.14 tail-call interpreter

#83

Earlier quoted context omitted.

Why would you want it to increment 1 if we decrement 1 from the same variable? That would be a waste of cycles and a good compiler knows how to optimize it out, or what am I misunderstanding here? What do you expect "it" to do and what does it really do? See: https://news.ycombinator.com/item?id=43320495

I'm pretty sure that's replying directly to the comment about how c is close to assembly and that if you add that line of code somewhere you know there's a variable getting incremented. Doesn't really matter whether or not it's useful, the point is that the behavior isn't exactly what you wrote

To reiterate, claiming that C can be described as "portable assembly" is not a claim that it is literally a package of assembler macros that emit deterministic machine code for each individual source expression.

I linked these in another comment, but here's some examples of straightforward-looking integer addition emitting more complex compiler output for other languages that compile to native code:

Haskell: https://godbolt.org/z/vdeMKMETT

C++: https://godbolt.org/z/dedcof9x5

Re: Performance of the Python 3.14 tail-call interpreter

#84

Hello. I'm the author of the PR that landed the tail-calling interpreter in CPython. First, I want to say thank you to Nelson for spending almost a month to get to the root of this issue. Secondly, I want to say I'm extremely embarrassed and sorry that I made such a huge oversight. I, and probably the rest of the CPython team did not expect the compiler we were using for the baseline to have that bug. I posted an apo…

You're doing great work pushing Python forwards. Thanks for all your efforts.

Re: Performance of the Python 3.14 tail-call interpreter

#85

Hello. I'm the author of the PR that landed the tail-calling interpreter in CPython. First, I want to say thank you to Nelson for spending almost a month to get to the root of this issue. Secondly, I want to say I'm extremely embarrassed and sorry that I made such a huge oversight. I, and probably the rest of the CPython team did not expect the compiler we were using for the baseline to have that bug. I posted an apo…

It's still a performance improvement, which at the scale of python deployment will probably mean quite a bit of global power savings :)

Re: Performance of the Python 3.14 tail-call interpreter

#86

Earlier quoted context omitted.

It means that "a += 1` is easy to understand as incrementing a numeric value by 1" is not true and instead "it can be really difficult to map between the original source and the machine code". More examples of non-trivial mapping from C code to generated code: https://godbolt.org/z/jab6vh6dM

All of those look pretty straightforward to me -- again, what assembly would you expect to be emitted in those cases? For contrast, here's the assembly generated for Haskell for integer addition: https://godbolt.org/z/vdeMKMETT And here's assembly for C++: https://godbolt.org/z/dedcof9x5

> All of those look pretty straightforward to me -- again, what assembly would you expect to be emitted in those cases?

It is very straightforward indeed, but it is still not mapping primitive operations to direct machine code, but it is forwarding to out-of-line code. Same as operator overloading in other languages.

> And here's assembly for C++: https://godbolt.org/z/dedcof9x5

That's just a symptom of allowing the compiler to inline the add code, otherwise the generated code is as straightforward:

   addOne(Int):
    push   rax
    mov    esi,0x1
    call   4010c0 
Ref: https://godbolt.org/z/xo1es9TcW

Re: Performance of the Python 3.14 tail-call interpreter

#87
post #28

Earlier quoted context omitted.

C might be low level from the perspective of other systems languages, but that is like calling Apollo 11 simple from the perspective of modern spacecraft. C as written is not all that close to what actually gets executed. For a small example, there are many compilers who would absolutely skip incrementing 'a' in the following code: uint32_t add_and_subtract_1(uint32_t a) { a += 1; a -= 1; return a; } Even though that…

Why would you want it to increment 1 if we decrement 1 from the same variable? That would be a waste of cycles and a good compiler knows how to optimize it out, or what am I misunderstanding here? What do you expect "it" to do and what does it really do? See: https://news.ycombinator.com/item?id=43320495

I'm not an embedded expert but a friend of mine has complained about compiler optimizations breaking things in his programs. I could see incrementing by one being used to set some bits in a memory location for a cycle that may mean something to some peripheral and then decrementing by one to set some other bits that may mean something else. In that case, the compiler removing those two lines would cause a very hard to debug issue.

Re: Performance of the Python 3.14 tail-call interpreter

#88

Earlier quoted context omitted.

The parent example can be made clearer like this: https://godbolt.org/z/MKWbz9W16 Dead code elimination only works here because integer overflow is UB.

Take a closer look at 'eru's example and my follow-up. He wrote an example where the result of `a+1` isn't necessary, so the compiler doesn't emit an ADDI even though the literal text of the C source contains the substring "a += 1". Your version has the same issue: unsigned int square2(unsigned int num) { unsigned int a = num; a += 1; if (num The return value doesn't depend on `a+1`, so the compiler can optimize it t…

In what world the return value doesn't depends on 'a' in this code?

  if (num 
A control dependency is still a dependency

Re: Performance of the Python 3.14 tail-call interpreter

#89
post #52

This is exactly the kind of content I love to see on HN. But I wonder though how this optimization is related to tail-call optimization? How the interpreter jump table is implemented shouldn't affect how stack frames are created, should it?

It's explained under the first link from the article [0]:

"A new type of interpreter has been added to CPython. It uses tail calls between small C functions that implement individual Python opcodes, rather than one large C case statement."

[0] https://docs.python.org/3.14/whatsnew/3.14.html#whatsnew314-...

Re: Performance of the Python 3.14 tail-call interpreter

#90

Hello. I'm the author of the PR that landed the tail-calling interpreter in CPython. First, I want to say thank you to Nelson for spending almost a month to get to the root of this issue. Secondly, I want to say I'm extremely embarrassed and sorry that I made such a huge oversight. I, and probably the rest of the CPython team did not expect the compiler we were using for the baseline to have that bug. I posted an apo…

Don't feel so bad. 1 to 5 % speedup is still an extremely valuable contribution.
Post reply on HN