User: Password:
|
|
Subscribe / Log in / New account

The trouble with volatile

The trouble with volatile

Posted May 11, 2007 21:50 UTC (Fri) by giraffedata (subscriber, #1954)
Parent article: The trouble with volatile

Linus' conclusion may be right, but his reasoning is all wrong.

First, while the purpose (reason for existence) of "volatile" is to prevent optimization, that's not what it's definition is. The keyword "volatile" does not say to not optimize; it says the value may change all by itself. So the fact that disabling optimization is a poor goal is not an argument against using "volatile."

Then Linus misinterprets the English word "volatile" and claims that data isn't volatile; rather accesses are volatile. The opposite is true.

I think he should have instead pointed out that some data is known to be involatile some of the time, so it is better if you can declare specifically when the data is volatile rather than just say it is volatile in general.

But the ways provided are just as over-general in the other direction. They say in a certain interval every memory location is volatile. There may be variables that due to circumstances cannot change while cpu_relax() runs. The program unnecessarily rereads memory.

I don't doubt that analysis shows that this over-generalization is better than the other over-generalization, but at least we should understand what comparison we're making.


(Log in to post comments)

The trouble with volatile

Posted May 14, 2007 7:16 UTC (Mon) by xoddam (subscriber, #2322) [Link]

Thanks girrafedata -- you have summed up all my niggling doubts about Linus' argument. His sweeping generalisations apply as well to explicit barriers as they do to volatile; they are undoubtedly the best solution to the problems they are used in the Linux kernel to solve, but they are not so much less general that his argument sweeps all before it.

What you don't mention (and Linus does) is that volatile can actually produce incorrect (as well as inefficient) code, because the compiler is not necessarily able to produce the right kind of barrier operation. Compilers know about instruction architectures and, maybe, something about which optimisations work best for which processor families, but they aren't oracles on the most appropriate bus synchronisation operations for every system architecture.

The trouble with volatile

Posted May 15, 2007 11:12 UTC (Tue) by IkeTo (subscriber, #2122) [Link]

> it says the value may change all by itself.

I think the inaccuracy and uselessness of this statement is what Linus is really objecting to. With this being inaccurate and useless, the compiler are forced to do useless things as a result. But those are side effects, the real culprit is still the inaccuracy and uselessness.

I believe the inaccuracy of "volatile" is that it says the memory is always changing, which is not really the case. The memory is changed by some other threads, or by some reordering done by some smart CPUs. It is definitely not "changing all the time", with the exception of I/O mapped memory which might.

I think it is mostly useless, because in most cases a simple "volatile" will not do what is intended, and to do what is intended you need something that will make volatile redundant.

E.g., if you are afraid of some other threads changing your variables, you need a lock to prevent that, rather than just an advice to the compiler not to optimize things out; and once you get that, the CPU reordering is dealt with, and the variable is no longer changing at all within the critical region, so you don't want volatile.

Another reply supplies another example: if you do inter-processor communications, "volatile" is not sufficient, because the instruction reordering done by the CPU causes the result to be erratic. You need something like barrier(), rmb(), wmb(), etc. Once you have that, "volatile" is redundant. Yes, those operations are over-general, but at least they work.

What if you really want to do I/O memory mapped read/write? Again, you need memory barriers for the code to work correctly, and once you have them, you don't need volatile.

> Then Linus misinterprets the English word "volatile" and claims that data
> isn't volatile; rather accesses are volatile. The opposite is true.

I agree that it is difficult to characterize an "access" is "volatile" or not, and I admit that I don't quite understand the statement. On the other hand, while "data is volatile" might be true for some time during the execution of the kernel, the "volatile" in the C language does not provide you the abstraction that you need most of the time.

The trouble with volatile

Posted May 16, 2007 11:43 UTC (Wed) by massimiliano (subscriber, #3048) [Link]

I agree that it is difficult to characterize an "access" is "volatile" or not, and I admit that I don't quite understand the statement. On the other hand, while "data is volatile" might be true for some time during the execution of the kernel, the "volatile" in the C language does not provide you the abstraction that you need most of the time.

A funny thing, that made me ring a bell...

In the .NET bytecode specification (called "CIL", Common Intermediate Language), there is the possibility to define something as "volatile", and... guess what? it is accesses that can be marked so, not variables!

This reinforces my idea that the .NET standard is very well thought out: they really learned from the mistakes of the past, at least on technical issues.

The trouble with volatile

Posted May 16, 2007 16:07 UTC (Wed) by giraffedata (subscriber, #1954) [Link]

In the .NET bytecode specification (called "CIL", Common Intermediate Language), there is the possibility to define something as "volatile", and... guess what? it is accesses that can be marked so, not variables!

This reinforces my idea that the .NET standard is very well thought out: they really learned from the mistakes of the past, at least on technical issues.

You're implying that "volatile" in C was a mistake. It wasn't. While it isn't useful for coordinating threads on separate processors in a 2007 Linux kernel, it's just fine for what it was designed for: coordinating a CPU with a memory-mapped I/O device in the early '80s.

I don't know anything about .NET, but I think the most you can conclude from this volatile thing is that .NET is designed for more modern computers than ANSI C. And that the spec is written poorly -- "volatile" is the wrong word for this.


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds