-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
allow choosing the initial stack size #5768
Comments
When you say that 'on x86_64 linux, a stack will be lazily allocated page-by-page anyway' that would only be true if the main task ran on the main thread and used its stack (or possibly if it used a pthread's stack), which it does not. The thread's stack is used by the scheduler, not tasks, and no tasks even run on the main thread by default. We could dedicate the main thread to the main task - it has been requested before - but it has a lot of consequences, making the main task 'special' in a number of ways (e.g. tasks that are expected to be on the main thread can never migrate to other threads, communication with the main task will have different performance characteristics than other general tasks). Personally, I like that there is no difference between the main task and any other task. It's consistent. It's also a little wasteful though since every program is guaranteed to have at least two threads. If the only goal is to avoid allocating stack segments then I think a solution in which users can declare that a function requires a large stack is sufficient, or one where they call a closure that preallocates a large stack.
|
I wasn't really thinking about a pthread stack vs. the stack segment Rust grabs with malloc since both will be allocated only when they actually touch a page. |
you're right about that of course. |
nominating feature-complete milestone |
One of my friends is presently writing a kernel with rust, so I asked what he's doing to deal with this, and he said he's set |
@bblum: it would be nice to be able to set it on a per-task basis though, so you can use tasks with big stacks (likely mapped 1:1 with threads) and still use a bunch of lightweight ones for I/O |
oh that's a good point. you couldn't get the removing-the-prelude optimization, but you could have a scheduler option to stop it from allocating. |
I think the best way to do this would be exposing the ability to choose the initial stack segment size in the do spawn(0) {
// smallest possible stack size, the current default
}
do spawn(std::os::stack_size()) {
// get the platform stack size from pthread_attr_getstacksize
}
do spawn(4 * 1024) {
// reserve close to the known required space, to get the best of both worlds
} It would be nice if we had default parameters... although we might disagree on the default. |
@bblum: When we do implement segmented stacks again, we could investigate the performance characteristics of using a single guard page at the end of every stack and catching the failure with a signal. It would mean the minimal stack size would be 8K (although it would never actually commit the second page), but we would be able to teach LLVM to emit all |
accepted for backwards-compatible milestone |
In today's meeting we have decided to jettison segmented stacks. I believe that the decision renders this issue moot because there's only one stack size for a task and it's always decided at the time the task is spawned. I may be wrong though, so feel free to reopen! |
So is there a way to set stack size nowdays? |
The main task could just start with a big stack segment (like 8MiB), and choosing whether a spawned task uses the conservative stack growth strategy could be optional. Segmented stacks are a scalability feature so the main task won't matter. On x86_64 Linux, a stack will be lazily allocated page-by-page anyway and the address space doesn't matter, it just won't shrink back down like a segmented stack. I don't know about other platforms.
The API could be opt-in or opt-out, as long as it's possible to use segmented stacks for scaling I/O and avoid them for code that really needs performance (memory locality matters a lot, the allocations themselves probably aren't too bad).
@brson, @pcwalton: any thoughts on whether this would be a sane thing to do?
The text was updated successfully, but these errors were encountered: