Write result to a volatile var to prevent dead-code elimination in tests

908 views Asked by At

I'm going to measure performance of some code. For the purpose, I introduced the following method:

def timed[T](body: => T) = {
  val start = System.currentTimeMillis
  blackHole = body
  val end = System.currentTimeMillis
  end - start
}

The blackHole variable introduced in order to preserve body result. This is done to prevent dead code elimination by JVM.

In some books there is a statement that blackHole should be declared as follows:

@volatile
var blackHole: Any = _

Why should one mark the variable volatile?

2

There are 2 answers

6
Ivan On

When you run code for quite a while, you will have Just In Time compiler (JIT) invoked for critical code parts. There are a few optimizations it will try to perform.

Dead code elimination. The code has no observable side effects, it can be removed.

You counter that by assigning the result to an instance variable you make harder to prove that the value is 'unused'. Potentially somebody from another class / thread can use that value later.

Volatile part wasn't really necessary in my benchmark. One of the blogs I read mentioned that JIT can drop writes for variables without it (link) though.

0
Dima On

The reason is that without volatile, that code is as dead as it was without the assignment. When you write to a non-volatile variable, the result of that operation is not guaranteed to be seen by other threads accessing that variable. So, as long as you are not reading the result back in the same thread, the write has never happened, as far as the outside world is concerned.