-
Notifications
You must be signed in to change notification settings - Fork 13k
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
array::map stack usage #86912
Comments
I did some analysis for the similar code: #![feature(array_map)]
pub fn main() {
(|| {
[0u8; 128 * 1024].map(|e| e + 1);
// Stack overflows, meaning the stack usage was more than 16 times the size of the array!
})();
} After some
|
Someone analyzed a similar problem on reddit: https://www.reddit.com/r/rust/comments/oeqqf7/unexpected_high_stack_usage/ |
Alas, the high stack usage when using large types by value, including arrays, is going to be a commonly recurring theme. There's a lot of reliance on optimization here to remove intermediate locals and to inline functions so that copies when passing arguments aren't necessary. |
The implementation of pub fn map<F, U>(self, mut f: F) -> [U; N]
where
F: FnMut(T) -> U,
{
let mut result: [U; N] = unsafe { std::mem::zeroed() };
for (i, x) in self.into_iter().enumerate() {
result[i] = f(x);
}
result
} (using the 2021 edition |
The issue seems to be resolved on Nigthly. |
not necessarily, the stack usage went from >16x the array size to >8x the array size, which imho is still excessive. |
You are using debug mode. Can you create an example which would work in release mode? Ideally it should be a godbolt link with enabled optimizations which clearly demonstrates unnecessary stack usage. |
@wrenger |
here's 3x stack usage in release mode: ideally it would be 2x if neither the source nor destination array of the |
compiler explorer demo of 3x stack usage: array size of 100kB: example::func:
push r15
push r14
push r12
push rbx
mov eax, 300024
call __rust_probestack
sub rsp, rax // <-- reserve 300k of stack space
... |
I think this link can be a slightly better demonstration: https://rust.godbolt.org/z/Wd7Ee8fzG We can clearly see that the map-based code for some reason does the following:
There are no side effects which prevent compiler from properly optimizing this code. Somewhat relevant issue: #88930 |
I have an example here where stack space for
|
I don't know if this is the right place for this, but I'd like to report that
array::map
uses the stack excessively and operating on larger arrays result in unexpected stack overflows.Minimal example: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=2d96e8f66b3432a8d1ecf0ca4331f85a
In the example, at some point more than 16 times more stack is used than the original array size.
As far as I've looked into the actual code, the only thing that stood out to me is use of
core::mem::transmute_copy
instead ofcore::mem::transmute
incore::array::IntoIter::new
, but I doubt it's the reason for this.Originally posted by @PonasKovas in #75243 (comment)
The text was updated successfully, but these errors were encountered: