Intel's "cripple AMD" function (2009)
agner.org
agner.org
Not to say Intel optimization is really good.
I assume you're payed based on final results, not based on source. Not so crazy of a concept - whoever delivered the best results got rewarded for it.
The class clearly has a performance component, and so students were expected to learn about optimization. Are they going to learn optimization better or worse if you mandate a single compiler? If merely switching compilers is the best path to performance, is that not a valuable lesson? If switching compilers and doing a bunch of extra work to make the code fast with the new compiler is the best path to performance, have they not learned a great deal?
You can always mandate a large set of compilers, make them all available, and leave it up to the students to determine which is fastest. I think that acheives both the competitive/educational goal and the level playing field goal.
Since then Intel settled the lawsuit by paying $10M and agreeing to add the following disclaimer to their compilers: "Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors..." http://software.intel.com/en-us/articles/optimization-notice... http://www.anandtech.com/show/3839/intel-settles-with-the-ft...
Whether or not the current page has anything to do with compilers.
Also, judging by the URL they made it an 'article' instead of a 'page' again... I'll have to see if I can get someone to fix that.
Is it just me or does that not actually fix the problem?
I don't agree either, but it's a perfectly valid solution (and probably the best for Intel's bottom line).
They should have originally used supported flags for different features instead of blacklisting the name, but it's still difficult to know what chips support what and whether it's worth using those features, due to different instruction latency, etc.
ICC get register dynamic code switching to different paths in the exe, so that if the chip supports AVX2, it'll use that code path.
they are not worried about fines. fines are cheap for those companies. they are worried about market control.
they are what they are thanks to phoenix reverse engineering IBM bios and the rise of the generic PC market. Now they fear anyone that can enter the market as easily as they entered and hope to not make the same mistake IBM did.
http://www.agner.org/optimize/optimizing_cpp.pdf
Instructions on how to patch Intel's CPU detection routine to do your bidding is in section 13.7, pp. 132-133.
The 2009 article also has this interesting tidbit: "It is possible to change the CPUID of AMD processors by using the AMD virtualization instructions. I hope that somebody will volunteer to make a program for this purpose. This will make it easy for anybody to check if their benchmark is fair and to improve the performance of software compiled with the Intel compiler on AMD processors."
There is no new info in the linked article regarding the "new" FTC investigation.
http://www.engadget.com/2009/05/13/intel-fined-1-45-billion-...
It would also tend to kill off the older companies (weak law of large numbers: if a company violates any of the laws that will kill it, and it exists long enough, it eventually gets caught and killed).
It might even lead to some efforts at counter-legislation. For example, companies might lobby to _broaden_ the "get killed" legislation, which would result in lots of sympathy cases where companies were killed for "minor" offenses. Eventually the whole "kill the company" idea would fall out of favor.
http://en.wikipedia.org/wiki/Three-strikes_law
(Companies will tend to view a government audit as a death sentence, since it would damage them so much even without a 300% fine.)
Also, an audit and 300% fines would probably not kill companies.
So in my books they still do quite a bit better than Broadcom, Realtek, etc.
Better than AMD, at least - just try finding the pinout of socket AM2, which was released over 7 years ago.
It's either that or support a company whose market advantage is based on anti-competitive practices and who will spend a significant portion of their profits on reducing consumer's choice of CPU (up to the point they no longer have to of course).
In my anecdotal opinion, Intel produces faster and better code than GCC and CLang about 2/3 of the time, with GCC usually second, and CLang slowest. I love the idea of CLang, but so far find it's main advantage to be clearer error messages rather than fast code.
Bugwise, I think they all are about equal. Intel's weakness right now (for my work) is that it crumbles under very high vector register pressure. And as a free academic licensee, support seems limited to posting on a forum and hoping a relevant Intel employee wanders by.
If I had just one shot for a compile and was hoping for the best outcome without being able to test and verify, I'd compile with Intel. But considering that GCC comes with source, has a much larger community, and accessible bug trackers, it's probably a better day-to-day compiler. But if you are trying to maximize performance, you should definitely try out Intel.
Most people don't care enough about performance to notice, but recompiling with Intel's compiler often shows a 5-15% difference on number crunching codes and that's before spending time investigating the vectorization output and fine-tuning.
On the other hand, if you really care about speed then someone with some experience in performance tuning will typically be able to make your code run 4-8x faster, vastly outweighing any benefits from the compiler.
Intel's compiler: 15% speedup
Hand-optimized code: 800% speedup
This gap in compiler tech is still a big deal today. Think about the early mainframes and how the code was all written in machine code or assembler. http://www.pbm.com/~lindahl/mel.html
Compilers can still improve, a lot.
• Parallel code? _still_ hand-written, even though choosing the right language/library can help. Note that choosing that language that makes parallelism easy may cost you when you actually go for the max parallel speedup
• GPU? hand-written. See: litecoin miners and bitcoin miners before that. OpenCL but were hand-tuned for a specific architecture
• Cross-platform? Java and C should be portable, but ask any Android developer how it really works
• And the one we're talking about here: number-crunching code? hand optimized!
I'm actually quite optimistic about the future of compilers. One of the reasons HN is so fun to read is that it comes up often.
It really depends.
Especially in how naively the "non-optimized" code was written.
I can see vectorization accelerate from 2x to 4x (per core), but not much more than that (which the Intel compiler does best)
But even GCC can vectorize better today than in the early days of 4.0
My personal best was a 9x speedup, partly by using SSSE3 and partly by some really good prefetching and non-temporal writes.
If you look at what I said in the very narrowest light, I agree that SSE2 all by itself typically delivers a 2x speedup per core over non-SSE code.
Either way, using percentages there seems really misleading. 15% versus 700% (or 800%) looks like a much bigger difference than 1.15 versus 8 if you're not careful when thinking about it.
That leaves a bad taste in my mouth.
[1] or maybe not ? are MS Cxx compilers inheriting from Intel ones ?
This is not an acceptable use of trademarks.
But if you were Intel, would you have your engineers work on competitors' products to make sure they are well supported on your line of tools? Before making an answer, consider that the core implementation of AMD cpus differ significanrly from those of Intel: instruction timings are slightly different, whether you look at them individually or in groups. It's not just a matter of turning a switch to get optimal performances, and that's just the tip of the iceberg.
Now, from a business standpoint, I think it could make sense for them to make their compiler produce fast code for any chip, but the legal implications of having a conccurent's product burn because of code produced with your compiler might make you think twice before going that road. Intel probably chose the safe road for a reason. Also, note that the produced code isn't crippled (as in, it doesn't make AMD cpu execute endless loops, or produce wrong results more than Intel's ones), it just follow the safest path.
This sounds a lot more like Intel know they make the best compiler, and knowingly put non Intel CPUs at a disadvantage because it would seem that they have a faster CPU.
> This sounds a lot more like Intel [...]
Just a thought here: should Intel do things to avoid sounding like bad competitors, or to give their customers the best product they can offer? We're engineers, we should also know not to fall for appearances, shouldn't we? I know, I supported my own reasoning with the legal aspect of things, which sometimes is not very reasonable in what it must handle. There goes my original point.
If code is dumb enough to try to use something low-level (let's use Bull Mountain RDRAND as an example) without checking for that specific feature bit, then it obviously is the code that is broken, leading to an illegal operation and it gets killed. That's not the CPU's fault.
Intel and AMD CPU manuals both pound in the point, too. In the sections on these advanced features they always insist that you check the feature bit first.
But more likely, it would mean slower code execution, as the code path wouldn't be optimised for AMD:
i.e. if the processor check thinks it's running an i7 Sandy Bridge, with an SSE float divide latency of 11, but the AMD chip has a latency of 23, so the unrolled loop that worked well for the i7 doesn't work at all for the AMD chip.
Apparently when run under virtualization, the CPUID instruction is intercepted and can thus be manipulated. There's also a github project for patching binaries generated from ICC to run the optimal code-paths even for AMD. But there doesn't seem to be a way to manipulate the hardware itself to change its vendor string.
In this case, it's not just that Intel isn't playing nice with AMD, it's that they're specifically using poor optimizations during compile if you're not using an Intel processor. That's not by accident, that's done on purpose to make non-Intel processors seem worse. What you're allowed to do while competing in the market changes when you're the dominant player in the market.
It's worth noting that performance and processors isn't as simple as "it has the feature, so use it". Each instructions have timings that vary on different models, and something like SSE(2|3|4) or AVX(2|512) can vary dramatically in its net benefit or detriment by the number of words, alignment, and so on. Many people with the ICC and code that they think will be super fast using it often are surprised to find it hasn't chosen to use them at all, simple setup and teardown eating all possible benefit.
In an ideal world we would have an open compilers that made best in class code for all major processors. Sadly that doesn't exist, and even now we have a case where a lot of the complaints about the ICC are "it crippled the code for my AMD....but still made better code than every other compiler".
All in all, you seem to be downplaying this far more than it deserves. It is not a case that the "compiler optimizes primarily for Intel processors". If it simply produced code built to be good on Intel and with no attention paid to AMD CPUs at all, that would be fine. Nobody would complain. Nobody would expect anything else, really. But that's not what they do: instead, they generate code that checks for an AMD CPU and then deliberately chooses a suboptimal path in that case. So it's not a case of "optimizes primarily for Intel processors", but rather "intentionally cripples performance on non-Intel processors". That is to say, there is a vast gulf between indifference and purposefully making things worse.
Do people realize that we're talking very specifically about auto vectorization? This is a very unique, niche area of software (and it is absolutely an optimization, various hysterics notwithstanding), and this notion that various random software you're running are being "crippled" is utterly nonsensical.
We seem to be talking past each other, so let me briefly summarize what's going on, since you keep talking about optimizations and how difficult they are, and that just doesn't matter.
Intel's compiler produces multiple code paths, each one optimized for different CPU features.
The generated code always runs the slowest "fallback" code path on AMD CPUs.
Other code paths are still faster than the "fallback" path, even on AMD CPUs, despite not being optimized specifically for them.
Thus, Intel is artificially reducing the performance of their generated code on AMD CPUs. They put in more work to make this happen. If they had simply left out the CPU vendor check, AMD CPUs would perform better.
It is entirely probable that simply running the "Intel" code chain will yield code slower than without on some sets of code with some sets of data, on some AMD architectures. Again, in most cases with vectorization you are not suddenly seeing a magnitude improvement, but rather something that can be marginal in some cases with some cases of data. It is a very hard problem, which is exactly why for all of the bluster the Intel Compiler is still considered the best compiler, 8 years into this controversy. AMD has been contributing to the Open64 compiler for years, but you don't hear much about it. And I'll bet their contributions don't put too much care into Intel processors.
2. New icc version adds check for "GenuineIntel".
3. New icc version now runs slowly on AMD.
ICC 8 added auto-vectorization. It, the very first auto-vectorization version, added the "GenuineIntel" branch for such vectorized code, because despite all of the fiction stated otherwise, vectorizing is actually a very hard task (hence why Intel maintains such a lead, and people are still griping about this 9 years after it came about).
I am hardly standing up for Intel, but this is Reddit-level conversation, where people simply say what they hope is true.
Yes, various optimizations, including auto-vectorization, are difficult. Why does that mean Intel had to add a check for Intel CPUs in their compiler?
The Intel compiler makes tight, fast x86[^1]. It ALSO can optionally generate auto-vectorized code paths for specific Intel architectures (it is not simply "has feature versus doesn't have feature", but instead chooses the usage profile of features based on the runtime architecture. Each architecture has significant nuances, setup and teardown costs, etc, and anyone who says "they should just feature sniff" does not understand the factors, though that certainly doesn't stop them from having an opinion), for that small amount of niche code that can be vectorized. Saying that because they don't do the latter for AMD processors means they "crippled" them is nonsensical.
Just to be clear, I have heavily used the Intel compiler for back-office financial applications. I'm not just repeating some opinion I happened across. Nor do I have any particularly love for Intel.
Further, if you understand that Intel specifically targets specific Intel architectures with every branch path, saying "well just run it on all things", again, you simply don't understand the discussion, or the architecture based dispatcher. Yeah, "just run it" might run perfectly fine, and for a contrived example might yield better runtimes, but it also can yield runtime errors or actual performance losses.
As I have repeatedly stated, we should expect great cross architecture and platform (including ARM, which with NEON also has vectorization) compilation with auto-vectorization from the dominant compilers, including GCC, LLVM, and VC. But somehow it always returns to the Intel compiler, nine years after they publicly stated "Yeah, this is for Intel targets".
^1 - So much so that in almost all of these conversations, the people who complain about Intel compilers still use them because it still generates the fastest code for AMD processors, vectorization or not. Which is pretty bizarre, really.
http://www.swallowtail.org/naughty-intel.shtml
According to that, the code simply does a feature check for SSE, SSE2, and SSE3. Except it also does a check for "GenuineIntel" and treats its absence as "no SSE of any kind" even if the CPU otherwise indicates that it does SSE. That check is completely unnecessary and does nothing but slow (or crash!) the code on non-Intel CPUs.
If you still think that's wrong, could you post the relevant code to show it?
Further the bulk of that entry was from 2004, which is pertinent given that at the time the new Pentium 4 was the first Intel processor with SSE2, and the SSE implementation on the Pentium III was somewhat of a disaster -- both single-precision width (it simulated 128-bits through two 64-bit operations, and for the P3 compilers could optimize for its specific handicap), and sharing resources with the floating point unit. So the feature flag, coupled with "GenuineIntel", was all they needed to know for the two possible Intel variants with support.
Since then the dispatcher and options have grown dramatically more complex as the number of architectures and permutations have exploded.
http://publicclu2.blogspot.com/2013/05/analysis-of-intel-com...
Unfortunately, it doesn't show the raw assembly. But in the absence of any information to the contrary, I'm perfectly happy to trust this pseudocode. It shows a bunch of feature checks, preceded by a single "GenuineIntel" check. The code that's gated on "GenuineIntel" would work just fine on non-Intel CPUs. It might sometimes produce sub-optimal results, but overall it'll be fine. There are some CPU family checks, but my understanding is that non-Intel CPUs return the same values that Intel CPUs do for similar architectures/capabilities.
We have multiple people saying that the code runs faster if the "GenuineIntel" checks are removed, we have pseudocode for the function in question that shows a bunch of feature detection with a bit of CPU family detection, neither of which are at all Intel specific. And then we have you, who can't seem to substantiate your claims at all.
If you have actual code or other reasonable evidence to support what you're saying, I'd love to see it. But right now, I'm not buying it.
That same debate might happen. But I doubt we'd see it, because most people would dismiss such a debate as stupid. Why would Intel put any effort into making their compiler optimize code for AMD CPUs?
Again: there is a world of difference between simply not optimizing for AMD, and deliberately running slow code when an AMD CPU is detected.
If Intel just checked CPU features and decided based on that, would it still produce bad code for AMD sometimes? Probably. Would it be as slow? Doesn't sound like it, from people with real-world experience with the compilers. Would people still complain? Yes. Would those complaints have any merit? No.
Instead of simply removing this code, which serves no purpose other than degrade performance on non-Intel CPUs, they reached an agreement to put legal disclaimers on every web page mentioning their compiler that they reserve the right to do this. But because of the slick legal language of the disclosure, most people get the impression that they are simply failing to make AMD specific optimizations, rather than intentionally preventing non-Intel CPUs from utilizing the optimizations already present in the code.
I think we all agree that at this point Intel's practice is fully legal. Their engineers should feel proud of having built a really solid compiler. But Intel-the-company deserves to be shamed for its slimy underhanded practices, and the engineers should feel a certain amount of revulsion for allowing themselves to be used in this way. Perhaps if they stood up for the obvious right approach, they could help change the company for the better.
It is relevant, if you consider that optimization isn't just counting cycles at individual instructions. Some optimization pass may be CPU agnostic (and the difference of performances between compilers on AMD probably show that aspect), and some very well depend on CPU peculiarities.
Also, if Intel must provide good support for all AMD chips, then they will have to do the same for any other competitor (and there are some iirc).
> they generate code that checks for an AMD CPU
Is it really what they do? Are they checking for "GenuineIntel" CPU, or for "AuthenticAMD" ones? There's a slight difference, even if AMD is their only real competitor atm.
Again, nobody in this discussion is saying that Intel must provide good support for all AMD chips. All anyone is saying is that Intel should stop explicitly checking for non-Intel chips and running deliberately slow code on them.
Again, it would be just fine if Intel optimized their compiler exclusively for Intel CPUs and let non-Intel CPUs deal with whatever code they generated. That's what everyone would expect Intel to do. Nobody sane expects Intel to optimize for AMD CPUs in their compiler. We just expect Intel not to put extra effort into crippling them.
And for people looking to extract every last bit of power from their chips (AMD or not), they might have to implement the path by hand anyway.
> rather than falling back to the worst possible code.
Note that (I think it might have been said elsewhere), it's not the worst possible code, but the least efficient one generated by the compiler (which happens to be quite good already). /pedantic mode
Edit: clarifications.
1. They decide to implement the best possible x86 compiler for all CPU vendors. In this case, they optimize for AMD chips (and anyone else selling x86 chips) just like they currently do for Intel, possibly including AMD-specific code paths.
2. They decide to implement the best possible compiler for Intel x86 CPUs. In this case, they should just ignore the existence of other vendors and do the best they can for their own stuff. If it runs fast on AMD, great. If it doesn't, not their problem.
I'm not sure which of those two what you said falls under, but I think it's one of those. Unfortunately, they have chosen a third path, where not only do they specialize for Intel, but they check for non-Intel and deliberately pessimize performance there.
As for the first choice, ideally Intel should do that to provide the best possible compiler out there, but that would really be shooting oneself in the foot, unless they are guaranteed to always have the upper hand on the hardware side. It would also require them to study AMD cpus deeply (how instructions get translated to microcode, how that microcode is optimized, etc) - they probably have people doing that (if that's legal).
Thanks for taking the time to answer me.
Edit: modified my upper comment.
I don't know if you are familiar with mainframe or similar computing technologies. When you buy an IBM mainframe (or Power unix box to a lesser extent), you're essentially metered by a CPU budget. You're not permitted to use the full capacity of your system unless you pay.
This case is a little different, but the point stands. Companies should not be allowed to sabotage the competition or hobble the ability of a device capable of doing a task from doing it. The free market works when the stakeholders don't cheat.
Intel makes the ICC seemingly to try to encourage the adoption of newer features in newer processors -- multi-threading for many-core processors, SSE, SSE2, SSE3, AVX, AVX2, soon AVX-512, etc. It is worth noting that simply using a feature (e.g. SSE, AVX) because it is there does not guarantee performance improvements in all scenarios -- the ICC uses specific model timings to make some of its choices.
The obvious solution for this problem is to never have a reason to use the ICC compiler. For the auto-vectorization and use of things like AVX be as advanced in gcc, llvm, and even the Microsoft compiler.
http://www.anandtech.com/show/3839/intel-settles-with-the-ft...
Intel's behavior continues to be scummy and reprehensible, but by adding the disclaimer to all pages regarding the compiler they are now legally compliant. Still, it's a good enough compiler that at times it may be worth using and patching the binary to avoid their dirty tricks.
They only started caring about power consumption when it was already obvious to everyone that ARM is going to pose a threat to them eventually. I think if everyone sees something that's by definition not "paranoia". To be paranoid, you have to see and believe something before others see it.
They only started caring about power consumption when
it was already obvious to everyone that ARM is going to
pose a threat to them eventually.
I'm being a bit pedantic, but it seems to me they refocused on power consumption beginning with the launch of the Pentium M (forerunner of the Core and Core 2 lines) which was released in 2003 and was surely in development several years before that.Or do you think they were thinking ahead to ARM already in ~2001 or so? Maybe they were... although I think they were thinking about targeting laptop sales in general at that point, not ARM specifically.
Intel's engineering prowess has to be respected, but how they got there by abusing their market position is deplorable. At this point I don't think there is any rational reason to buy AMD at any price point, they've been dominated so hard. (Buying ATI may not have helped, but these days that's the only part of AMD that's even still competitive.)
http://www.agner.org/optimize/blog/read.php?i=142 "It is so important to economize the use of the micro-op cache that I would give the advice never to unroll loops."
I don't know how AMD compares.
Also, in practice code is a tiny portion of the size of a typical application. Far more space is consumed by resources like images and sounds.
I know, their compiler produces the fastest code, but maybe you can get good (enough) results by using libraries and maybe some manual optimization
Is there something in binary that executes best-performing instructions (as opposed to execute just the instructions compiled in) when it's being executed on a specific CPU? If so, how exactly does it work?
For example, if you are adding 4 pairs of 64-bit numbers, and there's a special add-4-pairs-of-64-bit-numbers instruction, but it's specified as part of SSE4 (I made that up, but it's the kind of thing that you would find), then you can ask the CPU if it supports SSE4. If it does, then you say great, use this code path that requires SSE4, and we'll do the whole operation in three instructions: load, add, store. Or something.
However, if the CPU says that it doesn't support SSE4, then you'd better have a backup plan. It doesn't have to run as fast, but it should compute the same answer. If it's compiled C code (as opposed to hand-written assembler), the compiler will have you covered. Instead of a single SSE4 instruction, maybe it will take 4 regular 64-bit x86 add instructions instead.
(And if you've written it in assembler, then you probably provided the compiler with a backup C implementation to use if SSE4 isn't supported.)
Intel's compiler is being unfair to AMD CPUs because -- even if they support the instructions that you want -- it won't use them. It will unnecessarily fall back to the plain old non-SSE x86 instructions.