0

I am new to multithreading world and started getting into it. I found threading requires synchronization. Volatile is no more a reliable thing. I would like to know if synchronization object are cacheable by compiler or at any stage?

Platform/languages used : c++, win32, Windows

In c++, volatile keyword is used for objects which can not be cached by CPUs. But today's compilers do not strictly follow this. Is there is other way around to make synchronization objects non-cacheable (or other optimizations are not applied on those objects).

tl;dr: Are synchronization objects cacheable? If yes, how can you make it non-cacheable ?

7
  • It's really difficult to understand what you're asking: the question is kinda vague and unclear. What is your concern with regards to the synchronization object: i.e. what are you worried might happen to it? Commented Jul 7, 2011 at 3:56
  • if synchronization objects are being cached on multiple CPUs and not updated to memory. Is this happens ? Commented Jul 7, 2011 at 4:01
  • sure, a synchronization object may be cached, but that has very little impact on the synchronization block. As long as the actual reference to the object doesn't change (i.e. you don't make it point to a different object), then you have nothing to worry about. Commented Jul 7, 2011 at 4:12
  • What if one CPU updates memory and other don't get updated of new value ? Does it happen ? Or changes in memory updates CPU caches as well ? Commented Jul 7, 2011 at 4:23
  • As long as you don't change what your object is pointing to, it really doesn't matter what you do to that object. Commented Jul 7, 2011 at 4:25

3 Answers 3

1

I'm not sure I follow your question: compiler cache has almost nothing to do with multithreading. The only thing that a compiler cache would do is to increase your compilation speed by caching previous compilations.

Synchronization objects can be "cached" since they're any arbitrary object that you've decided to use for synchronization, but that has little effect on concurrency. The only thing that you need to care about when synchronizing is that when you have multiple threads contending for a resource, they must all synchronize on the same object in order to get read/write access to the resource.

I'm going to take a wild guess, based on your mentioning of volatile, and assume that you're worried a synchronization object may be cached in a thread's local cache and changes to the synchronization object from one thread may not be visible to another thread. This, however, is a flawed idea:

  1. When you call lock() or synchronize() (depending on the language), all you need to care about is that the lock is performed on the same object regardless of the internal state of the object.
  2. Once you've acquired a lock on an object, any resource that you're modifying within that lock scope will be modified by only one thread.
  3. Generally, you should use a synchronization object that will not change (ideally a readonly, const or final) and we're only talking about the reference here, not the content of the object itself. Here is an example:

    object sync = new object(); string something = "hello":

    void ModifySomething() { sync = new object();// <-- YOU SHOULD NEVER DO THIS!! lock(sync) { something = GenerateRandomString();
    } }

Now notice that every time a thread calls ModifySomething, the synchronization object will be replaced by an new object and the threads will never synchronize on the same object, therefore there may be concurrent writes to something.

Sign up to request clarification or add additional context in comments.

1 Comment

In case of multiple CPUs caching can be an enemy. Is there any way to make it non cacheable (in c++ volatile seems to have compiler dependent restrictions)
0

The question doesn't make much sense without specifying a run-time environment.


In the case of, Java, say, a synchronization object (an object used for synchronization) is just like any other object. The object is target of the synchronization, so volatile (which applies to member variables) is only needed if the variable containing the synchronization object can change. I would avoid a program design that needs such constructs.

Remember (again, in Java), it is the evaluation of an expression -- generally a variable access -- that results in the synchronization object to use. This evaluation is no different than any other in this aspect.

At the end of the day, however, it is just using the synchronization tools of a particular run-time/environment in a manner in which they are well-defined and well-behaving.

Happy coding.


Java, for instance, guarantees that synchronized(x) { foo }, where x is a particular object, will create a mutually exclusive critical region in which foo is executed. To do this it must do internal work to ensure the book-keeping data is flushed correctly across all processors/caches. However, these details are generally outside the scope of the run-time in terms of using the synchronization construct.

1 Comment

@Hem Update the original question. Also, what form of synchronization is being used pthreads? Other? Be specific. At the end of the day, the only thing of consequence is the guaranteed semantics of the library... (also strong/weak memory models may need to be taken into account).
0

Synchronization objects are necessarily managed by the OS, which also manages threads and caches. Therefore, it's the OS responsibility to deal with caches. If it somehow knows that a synchronization object is used only on a single CPU (e.g. because it didn't allocate the second CPU to your process), the OS may very well decide to keep the synchronization object in the fist CPU's cache. If it needs to be shared across CPU's, then that will happen too.

One practical consequence is that you'll always initialize synchronization objects. In C++, that's natural (the constructor takes care of that) but in other languages you must explicitly do so. The OS has to keep track of the synchronization objects.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.