4 ms·
I find it pretty interesting that you see a lot of people say 'within an order of magnitude of C' when talking about performance for dynamic languages and JITed
by RyanZAG 13y ago
I find it pretty interesting that you see a lot of people say 'within an order of magnitude of C' when talking about performance for dynamic languages and JITed VMs, etc. But they rarely take this kind of thing into account. If you wrote this in Python, you'd be trying to get your implementation close to that original number - 1733.4 MFLOPS - but there's not much discussion on the real target being 17985.4 MFLOPS which needs very specific coding. I think a lot of our code we write today is a lot more inefficient than we admit to.
- cliffbean 13y agoI guess it is at least useful to teach people that performance isn't one dimensional. Most people don't measure performance in MFLOPS, for example. Relative to the amount of code in the world there are vanishingly few loops which have this kind of 10x speedup just waiting for the right tuning.
- pjmlp 13y agoTrue, but you have many ways performance can be improved. On this specific case it was developer helping the gcc optimizer. These type of optimizations could produce worse code in another C compiler. Sometimes the code is already fast enough for the problem being solved, other times rewriting the algorithm could improve performance. Only in cases where every ms counts, does helping the compiler really matter.
- raphaelj 13y agoI agree that 17985.4 MFLOPS needs very specific coding. But the 1733.4 MFLOPS solution is a really naive one. Data locality and cache friendliness are two of the first things taught in high performance classes, with an obvious trick : iterating using row-major order like in the second case. This trivial optimization gives a 9419.8 MFLOPS throughput. I don't think "everyday code" like that is so inefficient given the maximum result which can be obtained (17985.4 MFLOPS).
- tmoertel 13y agoYes. And for the same reason, that's why you sometimes have to do things in assembly. No compiler is going to go against its own grain when generating code. Yet, sometimes, that's what you must do to eke out the necessary performance. As an example, while doing code for a 6809-based video game (see [1] for full war story), I had to use every single register on the processor, including the system-stack register and the direct-page register, to speed up a graphics routine. This meant that, while my code was running, the system effectively had no stack and couldn't use certain addressing modes. Further, it also meant that interrupts would corrupt whatever memory the stack register happened to be pointing to. All these problems were solvable – and the pain we had to go through to solve them was, for us, absolutely worth the 70% speed-up it bought us – but no compiler writer is going to incorporate tactics this weird into a compiler's optimization logic. If you need to go "full weird," assembly is often the only way. [1] http://blog.moertel.com/posts/2013-12-14-great-old-timey-game-programming-hack.html http://blog.moertel.com/posts/2013-12-14-great-old-timey-gam...
- deleted 13y ago[deleted]
- agumonkey 13y agoGoing on and off abstraction layers is not done enough. I like articles where the authors iterate/feedback through high level code and low level results. Saw some in clojure and was happy to have conscious notion of cpu cycles floating next to s-exps (of course I mean this comment to apply to any kind of abstraction layer).