3 ms·
> one thing no one mentioned is to arrange data in cache-friendly format I said: reducing pointer indirections and other cache friendly code (just saying!) I
by barrkel 9y ago
> one thing no one mentioned is to arrange data in cache-friendly format
I said: reducing pointer indirections and other cache friendly code (just saying!)
I agree that it's harder. It's harder because the platform is unpredictable and capricious, it's liable to change from one release to the next, and if you have C-oriented ideas around mechanical sympathy, they can lead you astray. For example, manual loop unrolling is seldom a win in Java (often, the array access checks kill you). What you want is to make your code simple enough for the JVM to unroll it (it'll be able to prove to itself that you don't exceed the bounds and elide checks, especially if you help out with an explicit comparison up front). You're in a dialogue with a reasonably smart compiler, and it's a bit of a guessing game hunting for the happy path. That's why my step 2 and 3 involve incrementally building up your algorithm: you want to stay on the happy path, because if you stray off it, you need to get back on to it again before you change more stuff.
Usually the way to go is to write straightforward code (common idioms get more optimization effort from the JVM team) and keep it simple enough to stay in the optimizer time budget (splitting it up where necessary).
- vardump 9y ago> For example, manual loop unrolling is seldom a win in Java Just like practically everywhere else. Besides, it increases code size, and can decrease performance just for that reason, L1 code cache spills. Intel CPUs have increasingly improved loop buffers as well. If the loop qualifies, unrolling has no positive effect at all. Low end microcontrollers are another matter, that's where unrolling can still sometimes yield significant wins. I think the biggest issue I had with high performance Java is lack of memory alignment control and (at least last time I checked) vector intrinsics. JNI time...
- physguy1123 9y agoI reliably see gains from unrolling relatively simple loops on very recent cpus. Going to 8+ iterations is usually overkill, but it can help. Sometimes one can split a dependency chain by unrolling as well.
- vardump 9y ago> I reliably see gains from unrolling relatively simple loops on very recent cpus. Maybe you didn't have multiple of 4 uops in the loop? Or hit some other (?) loop buffer limitation. Dependency chain splitting is also indeed a good reason to "unroll". Although it's a bit more complex transformation than simple unrolling.
- barrkel 9y agoLoop unrolling can definitely still be a win if it's in the form of vectorising or otherwise processing multiple elements at a time.