When we examined the code that was generated for the sparse matrix multiplication benchmark of Mint, we noticed that variables containing loop indices had become cross-stage persistent (CSP) variables, which necessitated an array lookup. This was much more expensive than directly accessing a final local variable.
I have now implemented lifting for primitive and boxed types as well as for strings. For example, the code
final int i = 1;
Code
used to generate code that looked like this:
public class $$Code1$$ implements edu.rice.cs.mint.runtime.Code
private Object [] $csp_table;
public $$Code1$$ (Object [] csp_table) { this.$csp_table = csp_table; }
public Integer run() {
return $csp_table[0];
}
}
Even though the value of i
was final, we retrieved the value from the CSP table. Now we lift this value, i.e. we create a code object for it and escape it into the bracket using a edu.rice.cs.mint.runtime.Lift.liftint
helper method:
public class Lift {
Code
}
The compiler internally transforms
Code
into an escape-and-lift that looks like
Code
Now the code that is generated looks as expected:
public class $$Code1$$ implements edu.rice.cs.mint.runtime.Code
private Object [] $csp_table;
public $$Code1$$ (Object [] csp_table) { this.$csp_table = csp_table; }
public Integer run() {
return 1;
}
}
This has lead to nice performance improvements in the matrix multiplication and loop unrolling benchmarks, and (perhaps more spectacularly) also in the Lint interpreter benchmarks. The staged Lint interpreter benchmarks now run 20 times as fast as the unstaged versions. Matrix multiplication shows a speedup of a factor of 4.8, and loop unrolling has a speedup of 2.3.
There is a new release of the Mint implementation (November 4, 2009) and a new version of DrJava with Mint (drjava-r5128-mint-r14460).
(Re-posted from The Java Mint Blog)