3 ms·
Your GCC and Clang are outdated and results are VERY UNFAIR in many aspects. Intel compiler violates IEEE 754 by reassociating multiplication and addition. It
by Lockal 13y ago
Your GCC and Clang are outdated and results are VERY UNFAIR in many aspects.
Intel compiler violates IEEE 754 by reassociating multiplication and addition. It you want to compare icc with other compilers, you should use -Ofast option with other compilers.
Also, if you compile this code with Clang 3.3, you will get the same assembly as with ICC. And with GCC 4.8 you will get even more optimal assembly. Check http://gcc.godbolt.org/ http://gcc.godbolt.org/ to see the result with different compilers (permalink to code: http://bit.ly/1euyjXZ http://bit.ly/1euyjXZ)
- nkurz 13y agoI appreciate your comment. The machine I ran this on has some strange issues that require us to keep around older versions of GCC and Clang, but I was able to install recent ICC. I hadn't known about the online compiler. That said, perhaps you could provide some numbers to back up what you are saying? I'd love to see what you think they should be. Seeing as the article is about providing rough faster estimations using series expansions, I'm OK with Intel's choice of optimizations. For GCC, does "-Ofast" do anything that "-O3 -ffast-math" doesn't? Because I tried that and it did not help. CLang threw up error messages when I tried, and since it wasn't my code I didn't bother deciphering. [Does godbolt.org give you any way to download the executable, or do you have to cut and paste the output and assemble that? I can't find a download feature, but it would seem very useful and I don't immediately see any security reasons that they wouldn't offer it.]
- nkurz 13y agoOK, I just tried on the same machine with GCC 4.8.0. Same results: ICC clobbers GCC. nate@fastpfor:~/lolengine$ g++-4.8.0 -std=c++11 poly.cpp -Ofast -march=corei7-avx -o g++-4.8.0_Ofast_march=corei7-avx nate@fastpfor:~/lolengine$ g++-4.8.0_Ofast_march\=corei7-avx sin: 18.373 ns sin1: 17.0716 ns sin2: 11.0505 ns sin3: 18.3832 ns sin4: 13.244 ns sin5: 12.8103 ns sin6: 12.0091 ns sin7: 11.4129 ns Entirely possible I'm doing something wrong. Maybe ICPC is inlining things into main() and not using the assembly I put on pastebin? But in any case, I think the ball is in your court. And with GCC 4.8 you will get even more optimal assembly. Please prove it. Is it optimal because you tested it and it ran faster, or because you believe it should be? I used to have faith in GCC, but having looked at a fair amount of generated SIMD x64 assembly, I now believe that ICC generates better code in most cases.
- Lockal 13y agoThe math is very simple: register spill is the same, GCC generates 7 vaddsd and 9 vmulsd. ICC generates 7 vaddsd and 15 vmulsd. addsd latency is 3, mulsd latency is 5. There are multiple add-multiply units on intel CPUs, but this code loads them all, so ICC should be 30% slower with this assembly. > Maybe ICPC is inlining things Check this. Looks like it generates vectorized code. I don't have Intel compiler, so all I can do here is to read assembly. > having looked at a fair amount of generated SIMD x64 assembly There are no SIMD in any of your asm files. All these sin1-sin7 functions accept only one double and return only one result. They work with 128-bit operands, but only the first 64-bit part contain values for operations.
- nkurz 13y agoThe math is very simple: register spill is the same, GCC generates 7 vaddsd and 9 vmulsd. ICC generates 7 vaddsd and 15 vmulsd. addsd latency is 3, mulsd latency is 5. I strongly disagree that it's simple: figuring out the actual performance on a real processor without running the code is far from simple. In particular, the ordering of the instructions can be crucial. Yes, it can be done, but it takes a lot more than counting instructions. Intel's IACA is the most useful tool I've found for this (free), but otherwise I just spend a lot of time with Agner Fog's execution port info. There are no SIMD in any of your asm files. You are absolutely correct. I put the objdump into pastebin, but did not actually look at this code. I just presumed it was vectorized from seeing the large jump in performance with '-mavx'. Looking closer, it looks like Intel is using a dispatch function, and has a separate vectorized version that it uses when it can. I need to go to sleep, but I'll post the whole objdump so you can inspect: http://pastebin.com/B3EBi0Lq http://pastebin.com/B3EBi0Lq And if you send me email (my address is in profile) I'll send you a binary to play with. Or if you tell me where to upload, I can do so.
- Lockal 13y ago-Ofast is just an option, that works with icc, gcc and clang 3.3. Maybe for gcc 4.8 it includes only "-O3 -ffast-math", but it can be changed in any moment.