Hi Joe!
Yes, it's almost certain that any JIT compiler will optimize away such operations.
At the moment, standard methods of communicating with the JIT compiler are somewhat limited, and not standardized.
To prevent such optimizations from happening, you should assign the result of your computation to a volatile variable.
For example, you could have a loop like this:
@volatile var dummy: Double = 0.0
def doBunchDouble(v: Double): Unit = {
var i = 0
val divDouble = divisor.toDouble
while (i < repsPerRun) {
dummy = v % divDouble
i += 1
}
}
However, this again, will almost certainly be optimized away, since the expression `v % divDouble` will be hoisted out of the loop.
This is a standard optimization, and you can count that the JIT will do it.
To prevent it, you need to use the loop-specific index in the expression:
while (i < repsPerRun) {
dummy = i % divDouble
i += 1
}
In case that volatile assignment is costly compared to a modulo operation, it might make sense to have several modulo operations per loop iteration.
while (i < repsPerRun) {
val tmp = i % divDouble
dummy = tmp % divDouble
i += 1
}
Even better, you might want to keep an accumulator variable, and assign to the volatile at the end of the loop.
Hopefully, the JIT should not be smart enough with arithmetic optimizations to optimize anything there, and the accumulator variable's value should be kept in a register at all times:
var x = 0.0
while (i < repsPerRun) {
val tmp = i % divDouble
x += tmp % divDouble
i += 1
}
dummy = x
Hope this helps!
Alex