Opened 8 months ago

Closed 8 months ago

Last modified 8 months ago

#16065 closed task (invalid)

Don't do stack squeezing during context switches in single-threaded programs to guarantee determinism in allocations

Reported by: sgraf Owned by:
Priority: normal Milestone:
Component: Runtime System Version: 8.6.3
Keywords: Cc: osa1, simonmar
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: #4450, #8861 Differential Rev(s):
Wiki Page:

Description (last modified by sgraf)

As #4450 and #8611 show, stack squeezing in the RTS makes allocation numbers between two different runs of the same binary non-deterministic, because its effect is depending on when context switches are bound to happen.

A short-term solution might be to deactivate stack squeezing for vulnerable benchmarks with +RTS -Z +RTS -V0 like in Phab:D5460, but IMO a more elegant solution would be to only deactivate stack squeezing in threadPause calls that happen due to context switches. Would you agree?

Change History (11)

comment:1 Changed 8 months ago by simonmar

Good catch, but I don't fully understand stack squeezing affects allocation. As far as I'm aware it should just reduce the stack size, not increase it, so it shouldn't require any extra allocation.

I'm OK with putting in some fix for this to make the benchmarks stable, but I'd like to completely understand the cause first.

comment:2 Changed 8 months ago by simonmar

Ah, I just realised what causes the allocation: if we *don't* do stack squeezing, then the larger stack size means that we might overflow the stack in the future, which will entail allocating for the new stack chunk.

comment:3 Changed 8 months ago by osa1

because its effect is depending on when context switches are bound to happen

Any ideas why -V0 doesn't fix this? It seems to have fixed the same problem in #4450.

comment:4 in reply to:  3 Changed 8 months ago by sgraf

Replying to osa1:

because its effect is depending on when context switches are bound to happen

Any ideas why -V0 doesn't fix this? It seems to have fixed the same problem in #4450.

Yes, it fixes that, too (https://ghc.haskell.org/trac/ghc/ticket/8611#comment:11). But it isn't enabled by default (and nor should it).

comment:5 Changed 8 months ago by osa1

I'm trying to understand; if both -V0 and -Z fix the non-deterministic allocations in some tests, why not enable -V0 instead of -Z in those tests? I don't prefer one over the other, I'm just trying to understand.

comment:6 Changed 8 months ago by sgraf

No reason, I just thought that -Z was less invasive. But I don't really know the implications of -V0, so YMMV...

comment:7 Changed 8 months ago by simonmar

To eliminate non-determinism, -V0 by itself is preferable. Stack squeezing itself is perfectly deterministic, the non-determinism arises when it is done at non-deterministic times, which is a result of time-based context switches.

Last edited 8 months ago by simonmar (previous) (diff)

comment:8 Changed 8 months ago by sgraf

Description: modified (diff)

Updated the patch for #8611 to reflect this.

comment:9 Changed 8 months ago by simonmar

I think we want to leave stack squeezing as it is. How would you make it deterministic? Just saying "only squeeze if we're about to switch to a different thread" would just move the problem to concurrent programs. +RTS -V0 is a solution that works for both single-threaded and concurrent programs, because it forces the context switches to happen at deterministic times.

comment:10 Changed 8 months ago by sgraf

Resolution: invalid
Status: newclosed

I agree. Let's fix nofib by doing +RTS -V0 for all single-threaded benchmarks!

comment:11 Changed 8 months ago by sgraf

Summary: Stack squeezing during context switches makes for non-determinism in allocationsDon't do stack squeezing during context switches in single-threaded programs to guarantee determinism in allocations
Note: See TracTickets for help on using tickets.