views:

457

answers:

4

I know that writing to a volatile variable flushes it from the memory of all the cpus, however I want to know if reads to a volatile variable are as fast as normal reads?

Can volatile variables ever be placed in the cpu cache or is it always fetched from the main memory?

A: 

volatile implies that the compiler cannot optimize the variable by placing its value in a CPU register. It must be accessed from main memory. It may, however, be placed in a CPU cache. The cache will guaranty consistency between any other CPUs/cores in the system. If the memory is mapped to IO, then things are a little more complicated. If it was designed as such, the hardware will prevent that address space from being cached and all accesses to that memory will go to the hardware. If there isn't such a design, the hardware designers may require extra CPU instructions to insure that the read/write goes through the caches, etc.

Typically, the 'volatile' keyword is only used for device drivers in operating systems.

drudru
That may be what volatile means in C, but it isn't what it means in Java. In Java, volatility is about whether one thread performing a read will "see" changes made by another thread. It's more than simply whether the value can be in a CPU register. The volatile keyword also prevents what kinds of reordering the JVM can do on code that uses the variable.
NamshubWriter
Here's a Dr Dobb's article that goes into a little more detail between the differences: http://www.ddj.com/hpc-high-performance-computing/212701484
PH
The reader didn't say java and was specifically mentioned 2nd level cache, so I assumed the most common scenario... C.
drudru
+5  A: 

The answer is somewhat architecture dependent. On an x86, there is no additional overhead associated with volatile reads.

JMM cookbook from Doug Lea, see architecture table near the bottom.

To clarify: There is not any additional overhead associated with the read itself. Memory barriers are used to ensure proper ordering. JSR-133 classifies four barriers "LoadLoad, LoadStore, StoreLoad, and StoreStore". Depending on the architecture, some of these barriers correspond to a "no-op", meaning no action is taken, others require a fence. There is no implicit cost associated with the Load itself, though one may be incurred if a fence is in place. In the case of the x86, only a StoreLoad barrier results in a fence.

Tim Bender
How can this be? What about multi-core processors? (Without reading the entire link you posted)
ripper234
+1  A: 

Volatile reads cannot be as quick, especially on multi-core CPUs (but also only single-core). The executing core has to fetch from the actual memory address to make sure it gets the current value - the variable indeed cannot be cached.

As opposed to one other answer here, volatile variables are not used just for device drivers! They are sometimes essential for writing high performance multi-threaded code!

ripper234
A: 

It is architecture dependent. What volatile does is tell the compiler not to optimise that variable away. It forces most operations to treat the variable's state as an unknown. Because it is volatile, it could be changed by another thread or some other hardware operation. So, reads will need to re-read the variable and operations will be of the read-modify-write kind.

This kind of variable is used for device drivers and also for synchronisation with in-memory mutexes/semaphores.

sybreon
Not relevant, the question is for Java.
ripper234
It's still relevant if you understand what volatility means.
sybreon
It means something slightly different in Java.
ripper234
@ripper234: I'm fed up of these people down-rating an answer when it is 100% perfectly viable. The above answer is absolutely correct in all ways, even for Java! Ripper234, I'd advise you re-evaluate your comment and downgrade!
Jeach