-
Notifications
You must be signed in to change notification settings - Fork 551
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
rmp: use std::atomic for Blif::call_id_ static data member #5989
Conversation
…ata member Protect concurrent access to the Blif::call_id_ using an atomic data type: it is cheaper than a lock and for a machine word it is sufficent. Resolves rmp in The-OpenROAD-Project#5981. Signed-off-by: Calin Cascaval <[email protected]>
15f1849
to
100e382
Compare
src/rmp/include/rmp/blif.h
Outdated
static int call_id_; | ||
static std::atomic<int> call_id_; |
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.
@QuantamHD I see no reason for this to be static at all. Can we just make it a class member?
Part of the goal in #5981 is to allow multiple instances of OpenRoad to operate on different designs independently. This would solve thread-safety but not isolation (you would get different values of call_id_ depending on what each instance is doing). |
@QuantamHD it if it is a class var there is no need for atomic or static. |
It's supposed to provide a unique id (for instance naming purposes) across the whole application even if threads are creating multiple blif objects.
|
The names will be unstable and if abc has any dependency on them then the results will be unstable. It seems better to put the counter inside the thread than share it regardless of atomic/lock. |
So making it thread_local? You need some way to persist the id across constructors. |
Are different threads adding to the same db? If so, then thread local won't ensure uniqueness (and requires a lock). If not then thread local would work. |
Thank you both for your comments.
By making it atomic, we ensure it is correctly incremented as a global counter ( It will also only count instances in the same process; that is, as long as we only spawn threads, we'll get the global counter behavior (and it is thread safe). If we fork a different process, that process will start counting from the current value, and the two processes will have overlapping sequences. What do we want?
Let me know which one of these is the intended design. |
No I think this is meant to be single threaded. @maliberty I think option 2 of @cc10512's should be what we move forward with. Do you concur? |
Does option 2 mean "So making it thread_local? You need some way to persist the id across constructors."? If so, yes. |
@maliberty option 2 means that you make it "instance local". You have a global counter that's thread safe, and if you save that in your instance, then each instance will have a unique value. What option 2 will not do is guarantee thread safety for instances -- that is, if you share an instance pointer across threads, then we'll have to look at the thread safety for all the other methods and data members. However, the since this new |
Creates a thread safe global counter for instances of the Blif class, and stores the counter as a data member to be used in instance methods. Signed-off-by: Calin Cascaval <[email protected]>
Based on our discussion until now, I believe option 2 is what we want. I pushed a commit to that effect so that @maliberty can see the code and decide. |
Here is a code example that shows how this works in a multithreaded environment:
Compile with The output of this program is:
I hope this convinces you that the handling of instances is thread safe. |
@@ -77,7 +77,7 @@ Blif::Blif(Logger* logger, | |||
{ | |||
logger_ = logger; | |||
open_sta_ = sta; | |||
call_id_++; | |||
instance_id_ = instance_counter_.fetch_add(1); |
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.
Equivalent to instance_id_ = instance_counter_++;
I am confused about the goal here. @QuantamHD is rewritting this code not use blif at all but to directly call abc. The current code doesn't use threads. It seems we are expending effort on condemned code. When we have multiple OpenRoad objects in a single process then we don't want any sharing through instance_counter_ even if atomic. It makes the object names non-deterministic and anything that depends on them will be such. @QuantamHD suggested have name generation happen in odb which is reasonable and would kill this variable altogether (replacing it with a non-static in the db). |
I hadn't had a chance to respond, but I realized you were right @maliberty. The end state we want is to have hermetic objects in the same thread. Design x1;
Design x2;
x1.doStuff();
x2.doStuff();
x1.writeVerilog();
x2.writeVerilog(); If we leave the static around the output of x1 and x2 will depend on the order in which they're run. We should in-fact move the counter to this class which has a 1-1 correspondence with Design https://github.com/The-OpenROAD-Project/OpenROAD/blob/master/src/rmp/include/rmp/Restructure.h as @maliberty. Sorry for the confusion @cc10512, we should in-fact remove the static and move it to Restructure.h and pipe it to this location. Otherwise we'll create non-hermetic outputs.
I need this functionality for my rewrite, so it's not wasted effort @maliberty |
Ok so it sounds like this PR is moot and you'll approach solving it as you suggest. |
Protect concurrent access to the Blif::call_id_ using an atomic data type: it is cheaper than a lock and for a machine word it is sufficent.
Resolves rmp in #5981.