5 ms·
One of the performance improvements mentioned is "Remove the usage of the C stack in Python to Python calls" [0]. Since Python 3.11, a Python-level function cal
by pansa2 2y ago
One of the performance improvements mentioned is "Remove the usage of the C stack in Python to Python calls" [0]. Since Python 3.11, a Python-level function call can be evaluated within the bytecode interpreter loop, no longer requiring a C-level function call.
Interestingly, Lua 5.4 did the opposite. Its implementation introduced C-level function calls for performance reasons [1] (although this change was reverted in 5.4.2 [2]).
[0] https://bugs.python.org/issue45256 https://bugs.python.org/issue45256
[1] https://github.com/lua/lua/commit/196c87c9cecfacf978f37de4ec69eba0a5971256 https://github.com/lua/lua/commit/196c87c9cecfacf978f37de4ec...
[1] https://github.com/lua/lua/commit/5d8ce05b3f6fad79e37ed21c1076e47a322472c6 https://github.com/lua/lua/commit/5d8ce05b3f6fad79e37ed21c10...
- alberth 2y agoDo you by chance know what LuaJIT does?
- mananaysiempre 2y agoIn JITted code? Nothing, it’s a pure tracing JIT so all calls are flattened. In the interpreter? We can always check the source[1], and it seems it implements its own stack. [1] https://repo.or.cz/luajit-2.0.git/blob/HEAD:/src/vm_x64.dasc https://repo.or.cz/luajit-2.0.git/blob/HEAD:/src/vm_x64.dasc: look for BC_CALL[2], then ins_call before that, then ins_callt just above it. [2] see mirror of the old wiki for the semantics: https://chrisfls.github.io/luajit-wiki/Bytecode/#Calls-and-Vararg-Handling https://chrisfls.github.io/luajit-wiki/Bytecode/#Calls-and-V...
- bongodongobob 2y agoCan you explain what this means? I know all these words, but it looks like retro-encabulator to me.
- pansa2 2y agoWhen one Python function calls another, does that ultimately result in the CPU executing a `call` instruction, or not? Python 3.11 changed from "yes" to "no" for performance reasons. Lua, OTOH, changed from "no" to "yes" in 5.4.0, again for performance. It then changed back to "no" in 5.4.2 for other reasons, despite the performance regression. (In Lua 5.1, instead of call/`return`, `coroutine.resume/yield` is implemented using C-level call/`return`. That would preclude implementing call/`return` the same way - but since 5.2 the coroutine functions are instead implemented via call/`longjmp`.)
- ufo 2y agoAt the heart of the Lua and Python interpreters, there's an evaluation function, written in C, that does something like this: void evaluate() { while (1) { instr = get_next_bytecode_instruction() switch(instr.type) { // run the instruction } } } The question is how to run a CALL bytecode instruction. One way is to use the C stack: call evaluate() recursively. The other way is to have the interpreter maintain its own call stack and the CALL instruction is responsible for updating said call stack. This way the interpreter stays in the same while(1) loop the whole time. Using the C stack can be faster, because you take advantage of the native instruction pointer & return address instead of emulating them in C. But it can also be slower if calling evaluate() is slow.