-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
[Refactor] Global stack map. #2628
base: staging
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left a few comments, but I'm in favor of these changes in general. Is there some specific benchmark where the memory impact could be measured? I'd be happy to run the numbers.
7acf383
to
6734bc4
Compare
7acf383
to
2c10b1d
Compare
self.stacks.read().contains_key(program_id) | ||
} | ||
|
||
/// Returns the stack for the given program ID. | ||
#[inline] | ||
pub fn get_stack(&self, program_id: impl TryInto<ProgramID<N>>) -> Result<&Arc<Stack<N>>> { | ||
pub fn get_stack(&self, program_id: impl TryInto<ProgramID<N>>) -> Result<Arc<Stack<N>>> { | ||
// Prepare the program ID. | ||
let program_id = program_id.try_into().map_err(|_| anyhow!("Invalid program ID"))?; | ||
// Acquire the read lock. | ||
let stacks = self.stacks.read(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any chance that the reads happen concurrently using e.g. rayon?
@kpandl found that my recent attempt at a stacks cache resulted in a deadlock - the cause still needs to be investigated but one potential reason could be ProvableHQ/snarkOS@970386f
@kpandl would be great if you can run a stress test with the same setup against this PR, you can let it run for half a day, and if there is no halt, increase the request pressure and we try again for half a day.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a broader question on what is the expected concurrency model of Process
.
I am assuming that there is a main thread which has R/W privilege and peripheral threads with R privilege.
One concern could be that the main thread runs into a read-write deadlock, but we've kept lock scopes minimal to avoid that. Perhaps the assumptions are wrong.
Curious to see the results of the stress test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to clarify what I think happened in ProvableHQ/snarkOS@970386f in order: 1. rayon spawns a number of threads which want to acquire the read-lock 2. the main thread wants to acquire the write-lock 3. another aforementioned rayon thread wants to acquire a new read-lock. However, rayon will only end all threads and release all read-locks atomically, so this new read-lock can't be acquired nor released, nor can the previous write-lock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's helpful context! I believe we are using parking_lot::RwLock which should prevent writer starvation. Perhaps there's a subtle way this is getting triggered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👌
d45aeed
to
919bee6
Compare
This PR removes
external_stacks
fromStack
and references all stacks through the global stack map inProcess
.This significantly reduces bookkeeping needed to keep
Process
consistent as stacks are modified or evicted from memory.The changes made in this PR should be semantically equivalent to the prior design.
While the weak reference from
Stack
toProcess
may have some overhead, it should not introduce memory leaks.An example
Suppose we have the following programs:
one.aleo
two.aleo
, which importsone.aleo
three.aleo
, which importsone.aleo
andtwo.aleo
four.aleo
, which importsone.aleo
,two.aleo
andthree.aleo
The existing

Process
andStack
s are organized in this way in memory:The new design is organized in this way:

The blue arrows are
Arc
s and the red arrows areWeak
s.