Wednesday, January 8, 2014

FeedaMail: Comments for Sutter’s Mill

feedamail.com Comments for Sutter's Mill

Comment on GotW #95: Thread Safety and Synchronization by Sebastian Bohmann

There’s a truly baffling number of incredibly deep sub-questions and sub-topics in that :)

(I know I’m overusing adjectives here from a stylistic point of view, but gosh…)

To me it’s a bit like, now that C++ finally is getting comprehensive abstract memory and threading models plus all the necessary abstractions in the STL, please go and learn everything possible about it… and I most certainly will attempt that, but I’m so looking forward to Herb’s answer post as a starting point ;)

Read More »

Comment on GotW #95: Thread Safety and Synchronization by Herb Sutter

The lack of answers is a sign that the question is either too easy or too hard. :) I doubt the former, and hopefully this GotW’s solution will help if it’s the latter…

Read More »

Comment on GotW #95: Thread Safety and Synchronization by sbohmann

Btw., Herb, would you say that C++ as of version /14 can now, as these high-level models for memory and concurrency have entered the stage, add CommonLisp to its tree of ancestors? :)

Read More »

Comment on GotW #95: Thread Safety and Synchronization by Luís Marques

My C++ is very rusty, but here is my 5:00 AM attempt!

1. Consider a concurrent system, where some data can be accessed concurrently by two or more threads, at least one of which might modify the shared data. A race condition is present in the program if it can result in a pattern of interleaved reads and writes that breaks the guarantees of the language or of the problem domain.

A race condition is very serious for various reasons. If we have a data race we are subject to undefined behavior in theory, and to torn writes in practice. Surely we do not want to access, say, a half written pointer? (In x86 perhaps that could happen in real-mode, when writing to a “far” pointer, if the segment and the offset were written by different instructions? Or a misaligned pointer? Particularly if it crosses cache lines and pages?). Even if we do not break the type system (perhaps “the language rules” might be more accurate?) a race condition in the problem domain logic is highly problematic, because the defect will tend to be very hard to reproduce and isolate, due to its non-deterministic nature.

2. A correctly synchronized program is one which is free of data races and where you observe the relevant data with the causality guarantees required by your program / problem domain (I suppose that second part is not required by the “data race free” first part?). Generally those causality guarantees would be achieved by providing sequential consistency on top of the more fundamental data synchronization steps? (the “atomic” bit in the atomics, as opposed to the ordering guarantees and in contrast with relaxed atomics?) (BTW, does that mean we have “total order for the parts of the program that matter to the relevant other parts”, if we don’t use relaxed atomics? Now that’s a confusing question!).

You achieve correct synchronization by first ditching your old broken compiler, and then not inserting race conditions of your own :-). That last part is done by either not mutating your data or by synchronizing access to it. That means you either make your objects internally synchronized (e.g., use an atomic, or require the object to be fundamentally thread-safe, like a mutex) or you use an external synchronization primitive, like a lock, to serialize and order your accesses.

3. (a). I suppose that this is not safe / correctly synchronized, because you have a data race and an int is not internally synchronized (is it?). BTW, (assuming that is correct) I would imagine that the Java memory model departs the C++ memory model here, and that you could not observe a torn write to an int (or other undefined behaviours). Is this a correct guess? If so, I suppose that implies you can only reasonably (with acceptable performance) implement concurrent Java in a system where the native types are guaranteed by the host system to be atomic (not in the C++ sense of providing ordering guarantees)

3. (b-d) Also not safe, but you can modify elements of the containers that you know won’t accessed by thread 1?

3. (e-g) These are correctly synchronized because they are internally synchronized?

It’s getting way too late, I’ll continue tomorrow/soon (I don’t know how long after the questions are the answers posted). I hope I was not too off base :-)

Read More »

Comment on GotW #95: Thread Safety and Synchronization by Bartosz Milewski

Since nobody raises their hand, let me give it a try.

1. I think there is some subtlety in the nomenclature: data race vs. race condition, so without looking at the Standard: More than one thread accessing the same memory location without synchronization, at least one of them writing. (The tricky part is the definition of synchronization.)

It’s deadly serious because a data race may go undetected for a long time until one day it causes a disaster.

2. A correctly synchronized program has no data races. You achieve it by making sure that all accesses to shared mutable memory are properly synchronized. The simplest approach is to associate a mutex with every such object (while trying to avoid deadlocks). If you’re adventurous, you may use atomics. If you are reckless, you may use weak atomics.

3. a, b, c, and d are not correctly synchronized. None provides its own synchronization. There is part of shared_ptr that’s thread safe — the reference counter — but that doesn’t protect the widget itself.

Mutex provides synchronization for other data and is designed to be accessed from multiple threads. So is condition_variable, although it can only be used in tandem with a mutex. That mutex, however, is not there to protect the condition_variable itself, but the data that’s used for signaling. Atomic variables are synchronized.

4 a. The code should provide mutual exclusion. Any access, read or write, must occur under a lock.

4 b. I’m not sure I understand this question. You probably have something very specific in mind. Shared data has to have the right granularity in order to be correctly protected — you can’t protect a single bit because there is no way to write a bit without touching other bits in the word.

4 c. This must be a tricky question. I would think that under total mutual exclusion you wouldn’t need any additional synchronization. Are you thinking of (multiple) reader / writer locks?

5. I guess this is more of a design question. I guess if you are exporting objects from a multithreading library and your library must access them concurrently with your client, these objects should have internal synchronization.

I’m sure there is much more to it, but that should be enough to start a discussion.

Read More »

Comment on GotW #95: Thread Safety and Synchronization by cmeerw

I guess for question 4 you have your “You Don't Know const and mutable” talk in mind (i.e. “const” means thread-safe)

Read More »

Comment on GotW #95: Thread Safety and Synchronization by Luís Marques

Weird. This second time my comment appears and says explicitly that “Your comment is awaiting moderation.” Must have been a bug the first time…

Read More »

Comment on GotW #95: Thread Safety and Synchronization by Luís Marques

Ah, my comment now appeared (was it stuck in moderation limbo? wordpress would only say I was repeating myself if I posted it again). When I posted my comment Bartosz Milewski had not replied yet, I see now that I was not too off base :-) Bartosz, please bring your wizardry back to the D world!

Read More »

Comment on GotW #95: Thread Safety and Synchronization by Xin Huang

I agree most on Bartosz’s reply, except for 4(c) which I don’t quite understand.

A little comment on 3(a):

It’s not safe to access an int concurrently, even only 1 thread will write. Because you will never know what the compiler would do, it can just load the int into one register and never read it again; or it can rewrite the int value back to the memory. (yes, unchanged value! See http://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong)

There is no benign data races.

Read More »

Comment on GotW #95: Thread Safety and Synchronization by Łukasz Łucek

Let me try my luck :) I should state that i’m not a native english speaker so don’t mind my writing problems.

So for the first two questions I think the answers are allready in the comments.

For question 3: mutex, condition_variable, and atomic are ok. Int is close but not quite there, because of possible code reordering and lack of sequential consistency.

4. (a) The tesponsibility of the code that uses a shared object is to make sure that when some thread is wrinting to an object it is the only thread that has access to this object. No other thread should be allowed acces to object neither for writing nor reading. On the other hand there can be many reader threads accessing the object in the same time, but as long as noone is writing to it.

4. (b) I belive that this “basic thread safety guarantee” is the constness of an object. That means that the type which is to be synchronized cannot change a single bit of itself in const methods. Especially copy constructor and comparison operations cannot change anything in the memory of an object.

4. (c) I Made a mistake in answer to (b), but it is on purpouse. An object is allowed to change its state (bits in memory) in the const operations as long as those changes are internally synchronizeb by that object. Only then this object can be properly externally synchronized.

5. My guess is that you should design types to be thread-safe if you intend to share objects of this type across threads :). If cost of designing and using such a type is lower than a cost of synchronizing objects of this type externally then go for it – the code using your type will be much nicer to read, and less error prone :). The tricky question is: Is it possible to make internal synchronization without signifficant cost on performance? For example can you afford to lock/unlock a mutex every time you use your variable.

Read More »
 
Delievered to you by Feedamail.
Unsubscribe

No comments:

Post a Comment