9 ms·
" I think DJB would argue that the compiler optimizations are insignificant in comparison to those improvements for a very large portion of hot code." Except h
by DannyBee 9y ago
" I think DJB would argue that the compiler optimizations are insignificant in comparison to those improvements for a very large portion of hot code."
Except he has no data to show this, and every piece of data i have (and my colleagues have), says that he is wrong.
Additionally, the compilers can and do replace algorithms if users let them. Most users don't want it, even if it makes code faster.
Remember that the vast majority of people want software that works and is reliable, or has fast development cycles, or a million other things, and happily choose that over software that is fast. Compilers changing algorithms on you isn't highly compatible with this, especially when, for example, most programming languages don't even give you a good way to express the invariants you are trying to maintain (except good ol' Ada).
However, besides that, certainly you can see that in the end, the people lose. It's like arguing that computer would never win at go.
If i really really really cared about some piece of hot code, i wouldn't pay an expert to optimize it, i'd throw the cycles of 100k spare cpus at optimizing it.
That is also the other strange part of his argument to me, he assumes the capabilities of compilers based on compilers he sees that are meant to operate pretty much single threaded on single machines, and complains "they will never beat people".
It's like looking at the machine learning algorithm that takes months or years or roughly forever to train on a single cpu and say "it'll never do a good job". The world is not that small anymore.
It's blindingly obvious the optimizing compilers win if we want them to.
In any case, this particular debate will restart again as gpus and accelerators follow the same old compiler cycle.
- oconnor0 9y ago> Additionally, the compilers can and do replace algorithms if users let them. Most users don't want it, even if it makes code faster. What compilers do this? With what algorithms?
- jerven 9y agoIf you look at modern JIT compilers such as Truffle-Ruby, then yes it will change algorithms. e.g. changing sort algorithms depending on data size. if the data is small enough it will do a bubblesort on registers, when its big it will do TimSort on heap data etc...[1] [1]: http://chrisseaton.com/rubytruffle/small-data-structures/ http://chrisseaton.com/rubytruffle/small-data-structures/
- coldtea 9y agoThis example is about the compiler changing between (existing) internal versions of sorting algorithms for language data structures. Not about changing what algorithms the user coded.
- danielbarla 9y agoExactly, that's two completely different things. It's akin to a compiler using the famous "switch statement becomes if-else chain if less than 7 items, otherwise lookup table". The parent posts are referring to macro-level optimisations, where large changes to how a system works are implemented, in order to get massive gains in performance. Picking out the essence of the larger implementation would be a difficult task for a compiler, but more importantly it wouldn't have enough information about the context of the application to make optimisation decisions. Things like: do we need to read from that file each time we need this piece information, or is it a once-off that can be cached? Unless this contextual information is expressed somehow (and it basically never is), only the programmer will be able to make the change.
- jerven 9y agodef clamp(num, min, max) [min, num, max].sort[1] end being turned into def clamp(num, min, max) if (num < min) { if (num < max) return num; else return max; } if (min < max) return min; else return max; end Seems to me to be algorithm rewriting. As is superword optimization and partial evaluation. All things that Truffle-Ruby + Graal do today.
- danielbarla 9y agoSure, and at this level, I would also argue that compilers are as good as humans at optimisation (likely better than almost all, actually). These arguments were constantly going on in the 80s and 90s, where (assembly-enthusiast) people vehemently argued that machines (C compilers) will never optimise things as well as humans. While the argument still exists in some form today, it's certainly died down a lot. That said, in my own limited experience, everyday optimisation problems tend to exist at a much higher level, on the high-level approach or "what are we doing" level. Perhaps these are "obvious" to some, or below the level of discussion here. But essentially, a compiler can optimise away endlessly at a piece of code, but will never beat code that shouldn't exist in the first place. My comment above was that a compiler has insufficient information to make decisions about what's truly wasteful or useless. As an example, no compiler today will come up with a Courgette update [1] by itself. And the day it does, I think we can pack up our bags and go home (hopefully in a nice, comfy retirement kind of way). [1] https://www.chromium.org/developers/design-documents/software-updates-courgette https://www.chromium.org/developers/design-documents/softwar...
- DannyBee 9y agohttps://books.google.com/books?id=u38h_fV3UqgC&pg=PA173&lpg=PA173&dq=algorithm+replacement+compiler&source=bl&ots=rThl4jM7eh&sig=tY4DnBKT4Pn_ZfnXRT2gGELxchI&hl=en&sa=X&ved=0ahUKEwjdwtXY_5vUAhUhw4MKHXe4DAgQ6AEIMTAB#v=onepage&q=algorithm%20replacement%20compiler&f=false https://books.google.com/books?id=u38h_fV3UqgC&pg=PA173&lpg=... See also the citations to it, http://dl.acm.org/citation.cfm?id=340757 http://dl.acm.org/citation.cfm?id=340757 See also https://www.researchgate.net/publication/221200232_Algorithm_Recognition_based_on_Demand-Driven_Data-flow_Analysis https://www.researchgate.net/publication/221200232_Algorithm... http://ieeexplore.ieee.org/abstract/document/5447280/ http://ieeexplore.ieee.org/abstract/document/5447280/ http://perso.ens-lyon.fr/christophe.alias/pub/alias_thesis.pdf http://perso.ens-lyon.fr/christophe.alias/pub/alias_thesis.p... https://www.ideals.illinois.edu/handle/2142/45394 https://www.ideals.illinois.edu/handle/2142/45394 http://gac.udc.es/~juan/papers/toplas.pdf http://gac.udc.es/~juan/papers/toplas.pdf and ... As the last paper says: "e. The development of techniques for automatic recognition of computational kernels such as inductions, reductions and array recurrences has been an intensive research area in the scope of compiler technology during the 90’s." If you want a simpler example, all of your compilers are usually replacing your divisions by a different algorithm :) It replaces your sum reductions, recurrences, etc. Seriously, these are really really old compiler problems. Compilers do the parts people care about, and will often replace the algorithms that are usually "slow", like math, or have well defined semantics that won't cause api breakage for you. Compilers replace memcpy, printf, etc, all the time. If you want a compiler that replaces your much higher level algorithms, as the papers show, they have existed over the years. When the research papers are scanned copies, it's old tech :P But the truth is that, for example, a lot of common languagers (C++, etc) are not good languages for that. It's not about compiler technology. I can teach a compiler to recognize your sorts, for example, pretty easily. But proving i can legally change it and not destroy the programming semantics is often literally not possible. You'd have to tell me "it's okay". It's only stuff that is well specified enough (like standard library functions) that i could do. Think about trying to swap STL data structures for some code. We can recognize when it is possible. We can even determine when it is profitable, and do it. Usually, the problem is it destroys the API you've built to do so (IE you pass it around as an argument), etc. and in the end, it's usually not worth it for those languages to do it in the compiler. It's infinitely more effective to do something like http://lists.llvm.org/pipermail/llvm-dev/2016-April/098355.html http://lists.llvm.org/pipermail/llvm-dev/2016-April/098355.h... and tell people "you should switch this datastructure". At least, for these languages. But hey, if you want the compiler to duplicate and inline all the functions and swap out the algorithms, it could! It's just that, for example, C and C++ are not languages that lends itself to compilers doing it, it's one that lends itself to telling humans to do it (or at least, asking them if they want it done and then doing it) This is obviously all easier in functional languages, and they actually have a fairly rich history of doing algorithm replacement :)
- Sean1708 9y agoAs a very simple example see if you can spot the loop in the optimised version of a sum to n function[0] (hint: you can't). I don't know to what extent this scales up to more complex programs, but it is at least possible in principle. [0]: https://godbolt.org/g/dRUYA3 https://godbolt.org/g/dRUYA3
- wolfgke 9y agoIt does not work very well: > https://godbolt.org/g/qmQhLK https://godbolt.org/g/qmQhLK Exercise: Write an assembly function that is faster than "-O3" and loop-free. Should be easy.
- wolfgke 9y agoUPDATE: For those who don't want to do the exercise: The Intel compiler (icc) optimizes it in about the way that I would if I were to write it in assembly: > https://godbolt.org/g/LntTnY https://godbolt.org/g/LntTnY
- AstralStorm 9y agoWhich is slower on non-Intel and older CPUs. Add -march=native next time. Nets you a vector version. If you disable sse it generates essentially what icc does with less reliance on ucode. See, rep is a workaround for older AMD CPU branch predictor. In addition gcc does not use the highly opcoded variant of lea with offsets because it is slow on older Intel. GCC version makes for much better speculative execution too due to the use of the adder.
- wolfgke 9y ago> Which is slower on non-Intel and older CPUs. Add -march=native next time. Nets you a vector version. Accepted (though the central advantage of SHLX (with-march=native) and SHL (no -march=native) for this example lies in the greater flexibility of register parameters). To my defense I only have a computer whose processor supports BMI2 for a few months now - so I could not play around with BMI2 before. Otherwise I am sure I would have known such tricks. > See, rep is a workaround for older AMD CPU branch predictor. In addition gcc does not use the highly opcoded variant of lea with offsets because it is slow on older Intel. I know that. My personal code philosophy is to avoid such hacks for circumventing performance bugs in outdated processors.
- flamedoge 9y ago> the compilers can and do replace algorithms if users let them I think idiom recognizers are worthy of mention. That said, it being a manual pattern recognition is probably going to eventually lose edge to things like LLVM souper or other superoptimizers (exhaustive or predictive)
- coldtea 9y ago>Except he has no data to show this, and every piece of data i have (and my colleagues have), says that he is wrong. That's because those data only represent quantitative statistics on code, not whether said code would get great benefits if the programmer actually bothered to make algorithmic adjustments.
- DannyBee 9y agoWhy do you assume we haven't measured what optimal looks like?
- flukus 9y ago> Remember that the vast majority of people want software that works and is reliable, or has fast development cycles, or a million other things, and happily choose that over software that is fast. People want software that is fast, slow (and bloated) software frustrates normal people, they just can't articulate it or identify the correct source of their frustrations. As I said in another post just yesterday, you'll often hear people say everything from "god I hate Microsoft" to "i think I need a new machine" to "I might have a virus". Once you dig into the problem it's often just a particular app (or bloated website) that is slow, or something else on the machine eating up way to much RAM and causing everything to swap. I'd love to run an experiment where group A has native apps written in a low level language and group B has entirely electron based ones. I'd bet my house that group B has a hell of a lot more general complaints.
- mpweiher 9y ago>> compiler optimizations are insignificant in comparison to those improvements > he has no data to show this Yes he does. And so do countless of other people. For example, I just gave a talk where I describe an afternoon optimization session giving me a 1000x and and 8000x improvement for a data-conversion and a query task, respectively. https://www.youtube.com/watch?v=kHG_zw75SjE https://www.youtube.com/watch?v=kHG_zw75SjE Was the compiler helpful? Probably, I didn't measure with and without. But the vast majority of the improvement was not the compiler. And I don't see how the compiler could have come up with the changes (moving from a layered architecture of Model Objects -> ORM -> SQLite to a hexagonal architecture with an optimized data representation and completely different access procedure for the one data type that mattered). And this is what I find almost everywhere I go. For example the BBC system I made somewhere between a hundred and a thousand times faster: https://www.slideshare.net/MarcelWeiher/in-processrest https://www.slideshare.net/MarcelWeiher/in-processrest , https://link.springer.com/chapter/10.1007/978-1-4614-9299-3_11 https://link.springer.com/chapter/10.1007/978-1-4614-9299-3_... And so on and so on. It is also interesting that in none of these cases did I revert to assembler, so I think that part of DJB's thesis is not entirely correct, but only in being too specific: hand-coding assembler is just one part of hand-optimizing, and very often it is not the or even a crucial part (though in security algorithms it might very well be). But the idea that optimizing compilers are getting squeezed at both ends is, IMHO, 100% correct. On the one hand, so much code is so incredibly cold, see Ruby on Rails web sites or most UI programming. RoR can do maybe 10-100 requests/s. It's so slow it's comical. However, most sites would be happy to receive 100 hits per day, so "comically slow" is fast enough. Or when I set the end-parameters for an animation that is going to take half a second, it wouldn't matter if the code doing that were run on a LISP interpreter badly written in Ruby. Or why hasn't PyPy completely replaced Python? Why was TCL adequate for steering supercomputer workloads? On the other hand, the performance critical parts have gotten more critical. That means that the "make everything a bit faster, but without any guarantees" that optimizing compilers are great at providing is simply not that useful any more for a lot of workloads. And yes, there are workloads where it is useful, and it seems that you have some of these workloads. That doesn't change the broader picture.
- regularfry 9y ago
- big_spammer 9y ago> most programming languages don't even give you a good way to express the invariants you are trying to maintain (except good ol' Ada). What does Ada do that helps with this in ways C and other languages don't?
- nostrademons 9y agoAda has a rich set of language features to express preconditions, postconditions, and invariants directly in the code, and then have those logical statements available to the compiler so that it can assume certain facts about the program's execution when optimizing: https://en.wikibooks.org/wiki/Ada_Programming/Contract_Based_Programming https://en.wikibooks.org/wiki/Ada_Programming/Contract_Based... Also, the type system lets you specify legal values with more precision than the word-based types that most languages inherited from C. For example, you can have range types that may hold integers of only a certain range, and the compiler will enforce that when assigning to variables of the type, or throw an exception if an arithmetic operation results in a value outside the range (you also have modulus types that explicitly give the wraparound behavior familiar in C). Containers allow generic constraints, and you can explicitly specify the dimensions of array types. https://en.wikibooks.org/wiki/Ada_Programming/Type_System https://en.wikibooks.org/wiki/Ada_Programming/Type_System