Java Reference
In-Depth Information
REGISTERS AND MAIN MEMORY
One of the most important optimizations a compiler can make involves when to use values from
main memory and when to store values in a register. Consider this code:
public
public class
class RegisterTest
RegisterTest {
private
private int
int sum ;
public
public void
void calculateSum ( int
int n ) {
for
for ( int
int i = 0 ; i < n ; i ++) {
sum += i ;
}
}
}
At some point in time, the sum instance variable must reside in main memory, but retrieving a
value from main memory is an expensive operation that takes multiple cycles to complete. If the
value of sum were to be retrieved from (and stored back to) main memory on every iteration of
this loop, performance would be dismal. Instead, the compiler will load a register with the initial
value of sum , perform the loop using that value in the register, and then (at an indeterminate point
in time) store the final result from the register back to main memory.
This kind of optimization is very effective, but it means that the semantics of thread synchroniza-
tion (see Chapter 9 ) are crucial to the behavior of the application. One thread cannot see the value
of a variable stored in the register used by another thread; synchronization makes it possible to
know exactly when the register is stored to main memory and available to other threads.
Register usage is a general optimization of the compiler, and when escape analysis is enabled (see
the end of this chapter), register use is quite aggressive.
Over time, say that the JVM notices that each time this statement is executed, obj1 is of type
java.lang.String . Then the JVM can produce compiled code that directly calls the
String.equals() method. Now the code is faster not only because it is compiled, but also
because it can skip the lookup of which method to call.
It's not quite as simple as that; it is quite possible the next time the code is executed that ob-
j1 refers to something other than a String , so the JVM has to produce compiled code that
deals with that possibility. Nonetheless, the overall compiled code here will be faster (at least
as long as obj1 continues to refer to a String ) because it skips the lookup of which method
to execute. That kind of optimization can only be made after running the code for a while
Search WWH ::




Custom Search