Skip to content
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

Increase stack size to 8 MB? #54998

Open
MilesCranmer opened this issue Jul 2, 2024 · 3 comments
Open

Increase stack size to 8 MB? #54998

MilesCranmer opened this issue Jul 2, 2024 · 3 comments

Comments

@MilesCranmer
Copy link
Sponsor Member

MilesCranmer commented Jul 2, 2024

The default stack size is 4 MB on 64-bit systems and 2 MB on 32-bit systems:

julia/src/options.h

Lines 112 to 120 in f2558c4

#if !defined(JL_STACK_SIZE)
#if defined(_COMPILER_ASAN_ENABLED_) || defined(_COMPILER_MSAN_ENABLED_)
#define JL_STACK_SIZE (64*1024*1024)
#elif defined(_P64)
#define JL_STACK_SIZE (4*1024*1024)
#else
#define JL_STACK_SIZE (2*1024*1024)
#endif
#endif

This can be a bit small for some applications. Since Julia favours building multiple dispatch interfaces with a lot of function aliases, I think a larger stack size is useful – for example, I ran into a stack overflow error here for a Enzyme differentiation of my codebase: EnzymeAD/Enzyme.jl#1156 (comment) which went away when I manually increased it to 8 MB with Task(f, 8 * 1024 * 1024). Apparently an AbstractGP maintainer had a similar issue when applying AD to some GPs.

I am wondering if the default stack size for 64-bit OSes could be increased to 8 MB, to match glibc? I don't know how easy it is to set it based on ulimit -s, which seems to be what other languages do (at runtime, rather than compiling it).

Seems like parts of Julia also reference an 8 MB stack size as being the default

julia/src/signals-unix.c

Lines 40 to 41 in 1193997

// 8M signal stack, same as default stack size (though we barely use this)
static const size_t sig_stack_size = 8 * 1024 * 1024;

For glibc, the default is roughly 7.4 MB. Here are the defaults for C across systems according to this old post: https://lists.gnu.org/archive/html/bug-coreutils/2009-10/msg00262.html

The default thread stack size is:

  • glibc i386, x86_64 7.4 MB
  • Tru64 5.1 5.2 MB
  • Cygwin 1.8 MB
  • Solaris 7..10 1 MB
  • MacOS X 10.5 460 KB
  • AIX 5 98 KB
  • OpenBSD 4.0 64 KB
  • HP-UX 11 16 KB

And the default stack size for sigaltstack, SIGSTKSZ, is

  • only 16 KB on some platforms: IRIX, OSF/1, Haiku.
  • only 8 KB on some platforms: glibc, NetBSD, OpenBSD, HP-UX, Solaris.
  • only 4 KB on some platforms: AIX.

Bruno


P.S., could the Task(f, n) API be documented? Regardless of interest in changing the stack size, I think it would be useful to have an official way of changing it manually for specific tasks.

@nsajko
Copy link
Contributor

nsajko commented Jul 2, 2024

It seems like increasing the default stack size could cause performance regressions for code using many Tasks?

could the Task(f, n) API be documented? Regardless of interest in changing the stack size, I think it would be useful to have an official way of changing it manually for specific tasks.

#55005 🙏

@MilesCranmer
Copy link
Sponsor Member Author

MilesCranmer commented Jul 2, 2024

Thanks for posting the issue!

Regarding performance, the only direct effect would be reserving more virtual memory for the stack. Performance would not inherently be affected because the stack is allocated in virtual memory, not physical – only when you use that allocated space for the stack does it allocate memory. i.e., the only direct effect would be less available virtual memory, as each task would take up more of the virtual address space. (using virtual memory itself is only an issue on 32-bit systems = 4 gigabytes in total; but 64-bit has a ton of virtual address space = 16 exabytes)

However, if you were to now use that larger stack, and have deeper function calls, then one could encounter performance regressions due to the greater memory usage. But the limit itself doesn't affect performance, only available virtual memory (of which, on modern 64-bit systems, it’s basically limitless). The practical concern of overly large stack sizes is users may start to use deep stacks. Since 8 MB is the default at the operating system I think it’s reasonable, especially given how composable the Julia ecosystem is, and it’s useful considering how AD tools can get quite deep call stacks.

@ViralBShah
Copy link
Member

Is this something we could enable on 1.12-dev and observe if there is a meaningful impact on performance? Seems like a nice easy win if we can have it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants