Read this. Seriously, go and read it, I’ll wait right here for you.
Done? Great, now let’s move on
with this post.
If you were obedient then you’d
know that in the post referred above, I bestowed some heavy praise on the usage
of the keyword register. I placed some serious weight on the importance and
effectiveness of using it. What if I were to tell you that this whole thing was
a setup? That I had this post planned up at the time of writing that one, would
you believe me then? Probably not, but here I am, in a somewhat myth busting
capacity, hoping to debunk an inception of thought that I may have put in your
head before.
Firstly I would like to tell you
that using the register keyword is often unnecessary and sometimes even
counterproductive. Compilers are smart and enough to recognize which variables are
referenced heavily inside of our program. Compilers are benevolent. and enough to
do optimizations (the kind of which are achieved by the register keyword) for
us, automatically.
The problem with using register
is the fact that a variable in a CPU register is in a place too important to be
treated as a normal memory address. Simply put, we are not allowed to play
around with the address of such a register. The compiler will simply slap an
error if we tried any of the pointer concepts on a register variable. This issue
is so severe that it has rendered the entire legacy of the register keyword,
obsolete and its future, gloomy.
Let me establish one thing,
compilers are capable (and eager) to optimize our program for us in ways that
go beyond limiting the distance between the variables and the processor. The
compiler optimization is a big topic and deserves a dedicated post but the primary
purpose of this post is introducing the usage of the keyword volatile. Don’t feel
cheated, the above text is there for a reason. Volatile is related to compiler
optimization in a very direct way. But before I go into that, let me first
describe what volatile is and what its job is:
Volatile is a data type modifier
(like register). This means that it is used when a variable is defined, like
so:
volatile int x;
What this tells the compiler is
that the associated variable can receive a new value from any source at any
time. Assignments like x = 5, are not the only way in which this variable will
be overwritten. A borrowed definition is:
The volatile modifier tells the
compiler that a variable's value may be changed in ways not explicitly
specified by the program. This means that a variable can have a change in value
without an assignment statement.
This instructs the compiler to
explicitly fetch the latest value of the variable every time it is to be used
preventing the compiler from performing any trick for the purposes of
optimizing the whole fetching the variable from memory saga. So, when you want
to prevent a particular variable from the compiler’s optimizations, then using
the volatile keyword with the variable definition would be the preferred way to
do it. Let’s look at an example scenario, shall we?
int time;
int CurrentTime;
time = CurrentTime;
/*some amount of time would have
passed between these statements, no matter how tiny that amount be./*
While(CurrentTime – time ==
TARGET)
{
//Do
Something.
}
In this example, the variable time is assigned the value of CurrentTime which is another variable which you can
assume returns the current system time at the time of invoking of this
variable. In the next statement, we see a while loop which checks to see if the
difference between current system time and the variable time is equal to some
target. Now, if the compiler is allowed to optimize the whole code, it’ll come
to the conclusion that since CurrentTime was assigned to time just immediately
before this check statement, the two variables must contain the same
value (considering that there are no statements in between that effect the
value of either of these two variables). This would then lead the compiler to
ignorantly evaluate the left hand side of the check condition to zero. Undesired
and inaccurate, the compiler’s optimization can’t be allowed in this particular
case.
How can we stop compiler from finding
shortcuts in variables accesses? By forcing it to follow the right way of
accessing the variable, every time it is to be accessed. And this, my dear
reader is done using the volatile keyword. In above example, the variable
CurrentTime is to be made volatile, and
the whole program will fall into place.
No comments:
Post a Comment