Hi John,<div><br></div><div>Yes, I&#39;ve read that blog post in the link before. We&#39;ll make sure we investigate thoroughly and post empirical test results the next time we post performance-related patches.</div><div><br>
</div><div>Thanks for reminding that :-)</div><div><br></div><div>There&#39;s a related question that I&#39;m looking for advice. We&#39;ve seen some of our Java apps having to call native code extensively, through JNI. The team that developed the library in native code doesn&#39;t have the resource to re-write the whole thing to a Java version, so the clients from Java side are stuck with JNI. That&#39;s not really &quot;typical workload&quot;, but it&#39;s happening on our production site. Running standard benchmarks like SPECjvm or SPECjbb wouldn&#39;t exercise JNI invocations that frequently, so perf improvements in the JNI wrappers won&#39;t show up significantly in these benchmarks.</div>
<div><br></div><div>How should we benchmark for situations like this? Should we run the standard benchmarks to show that performance doesn&#39;t degrade on typical workloads, and that it improves in a special case?</div><div>
<br></div><div>Regards,</div><div>Kris Mok<br><br><div class="gmail_quote">On Wed, Feb 8, 2012 at 7:46 AM, John Rose <span dir="ltr">&lt;<a href="mailto:john.r.rose@oracle.com">john.r.rose@oracle.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div class="im"><div>On Feb 6, 2012, at 6:20 PM, Krystal Mok wrote:</div><br></div>
<div class="im"><blockquote type="cite"><span style="border-collapse:separate;font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:medium"><div>
The original thinking behind modifying the UEP sequence in native wrapper is that the more space it takes, the more likely it&#39;ll become a code bubble that affects i-cache. The patch in the earlier post also modified the place where it checks thread state, which should also reduce code bubble for the common case.</div>
</span></blockquote><br></div></div><div>Let&#39;s remember to control our tendency (I mean yours, mine, and everybody&#39;s) to make optimizations prematurely.</div><div><br></div><div>Just because a bit of code looks ugly, or a data structure contains a surplus byte, does *not* mean it will pay to smooth it out.  Remember the following maxim: &quot;If you touch it it will break.&quot;[1]  In the case of Hotspot, we have many times seen simple, innocuous changes cause unanticipated breakage, in either correctness or performance.  To change the metaphor to binoculars or camera lenses, vigorously removing the lint can scratch the finish.  A well-intentioned change can include unintentional costs, including escalating source code complexity, surprising performance interactions, noisy skew between versions or across ports, or schedule slips due to stress test failures.</div>
<div><br></div><div>In this case, when removing icache bubbles, it would be best to detect them in real benchmarks (not micro-benchmarks) and then follow this paradigm:  First fix the problems that are known to affect performance.  Such work will probably occupy more than half of our professional time, because there are plenty of such problems.  To turn around the logic, if you see impossibly bubbly code (like nop sequences) in hotspot output, that is prima facie evidence that the &quot;bad&quot; code is irrelevant to performance, and probably also non-trivial to clean up.</div>
<div><br></div><div>I apologize if you have already done the empirical investigations for this case, and I know everyone already knows these generalities.  But I can also tell you that, at least in the teams I have been on, if we don&#39;t remind ourselves from time to time to pick the tasks that matter (and can be proved to matter), we will become less effective as engineers.  Nobody wants that, so I&#39;m reminding.</div>
<div><br></div><div>In the case of UEP, it seems likely that those instructions are usually not in code cache for typical workloads.  A code cache block contains many words of header information, immediately preceding the UEP, and all of that stuff appears to be irrelevant to performance.  If we want to experiment with cache effects, I suggest that a more fruitful line of investigation would be to either rigidly segregate hot nmethod code from all other nmethod contents, or do cache-line aware assignment (coloring) and padding to pack the hot nmethod code (post UEP, almost always) most tightly into icache.  I think OS engineers use similar techniques for perturbing thread stack addresses, to spread stack frames more evenly across dcache.</div>
<div><br></div><div>(And, to be clear, I do believe passionately in the value of code cleanups, and hope that every change can leave the workspace cleaner than before.  The best engineering change, IMO, is one which throws away bad code and finds a cleaner-and-better solution for a difficult-and-practical problem.  Another good change tweaks the system in an obviously correct way, without increasing source complexity, to achieve a localized beneficial result.  Tom&#39;s suggestion of moving the UEP up past the nops sounds to me like such a thing.)</div>
<div><br></div><div>Hope this helps...</div><div>-- John</div><div><br></div><div>[1] <a href="http://blogs.oracle.com/jrose/entry/three_software_proverbs" target="_blank">http://blogs.oracle.com/jrose/entry/three_software_proverbs</a></div>
</div></blockquote></div><br></div>