-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inline module for zero-cost tail call among multiple functions (mutral recursion) #20
Comments
Yes, I do think that would work. I suggested something similar here: #3 (comment) I need to push up my branch, but I am am privately working on a different solution based on stack allocated thunks which would not require a module-level annotation. The main problem that approach has is that since Rust does not yet support DSTs on the stack, a concervatively large size (and alignment) has to be chosen for the thunk data. It would be interesting to benchmark both approaches. In the enum case, you are still going to allocate as much stack space as the largest variant, so I am not sure which will be better. |
Hey @alecdotninja, thanks for getting back. I hope this idea above would be relatively easy to implement. Sorry for not seeing your prior similar suggestion. Please don't worry about the stack space allocation. It is only done once for the whole recursion, and allocation/deallocation take only one instruction regardless of the size, if I understand correctly: see compiler output line 147. This allocation is not that big unless you are crazy about your function arguments, and probably lives in the L1 cache which is plenty fast. |
There is no need to be sorry, @SichangHe ! I appreciate your thought in this space. I've created a new draft PR with my in progress work on the new Thunk-based runtime system. If you have any ideas or thoughts on the current implementation, I would welcome any feedback there. |
Intuitively, #21 adds the overhead of copying the closure and it vtable pointer (16 bytes) doing vtable lookup (one memory load) every call. |
There is an easy way to work around this, but it duplicates code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c0f7b792bb666cff0e327fce10215d72 |
It would be similar to PyO3/pyo3#3815 and look like this:
And expand to something like:
oddity
module) would be fed into thetailcall_module
proc macro.[is_even, is_odd]
annotated withtailcall::multi_tailcall
.__TailCallState
representing the arguments for each function.__multi_tailcall
function that takes a__TailCallState
and runs the loop, inlining each tail-call function's content with modification just like how it is done currently for single recursion.__TailCallState
and simply call the internal function__multi_tailcall
with that state.What do you think about this idea?
The text was updated successfully, but these errors were encountered: