Slashdot Mirror


Comparing G++ and Intel Compilers and Vectorized Code

Nerval's Lobster writes "A compiler can take your C++ loops and create vectorized assembly code for you. It's obviously important that you RTFM and fully understand compiler options (especially since the defaults may not be what you want or think you're getting), but even then, do you trust that the compiler is generating the best code for you? Developer and editor Jeff Cogswell compares the g++ and Intel compilers when it comes to generating vectorized code, building off a previous test that examined the g++ compiler's vectorization abilities, and comes to some definite conclusions. 'The g++ compiler did well up against the Intel compiler,' he wrote. 'I was troubled by how different the generated assembly code was between the 4.7 and 4.8.1 compilers—not just with the vectorization but throughout the code.' Do you agree?"

225 comments

  1. Documentation is King by jpschaaf · · Score: 3, Interesting

    For better or worse, I've always given the intel compiler the benefit of the doubt. They have access to documents that the GCC folks don't.

    1. Re:Documentation is King by Kookus · · Score: 2

      The place I work has lots of documents generated about decisions made, why those decisions were made, etc...
      They are really helpful documents that save a bunch of time... if only people would read them 6 months later when they should.

      Nah, people seem to ask for documentation third. Google first, co-workers second. Only until they run into a co-worker that says RTFM do they get to the third option of reading it :)

    2. Re:Documentation is King by Curupira · · Score: 5, Informative

      Yeah, on Intel processors. What about AMD and other x86 processors? Don't ever forget that ICC was once caught red-handed disabling important features when the CPUID did not return GenuineIntel...

    3. Re:Documentation is King by Anonymous Coward · · Score: 1

      Yeah, because Intel should be forced to provide free optimizations for their competitors. Wait, whuh?

    4. Re:Documentation is King by CajunArson · · Score: 1, Flamebait

      I'm sorry, you lost the right to put on the whole "Oh poor little AMD is being abused by the big bad monopolist!" the day that AMD came out with Mantle and started leveraging it's 100% monopoly in the console market in a much much worse way than Intel ever did with its 70 - 80% "monopoly" in the desktop market.

      --
      AntiFA: An abbreviation for Anti First Amendment.
    5. Re:Documentation is King by jmac_the_man · · Score: 2, Informative
      Intel isn't providing the optimizations for free to their competitors.* Intel provides the compiler, along with all its optimizations, to its customers in exchange for payment.

      *Except the academic, evaluation and Linux-only non-commercial use versions, which could theoretically be downloaded by AMD employees, I guess.

    6. Re:Documentation is King by Runaway1956 · · Score: 4, Interesting

      Yep, they have access to some cool documents. It took a lot of work to document the fact that the intel compiler was actually crippling code if it was run on AMD processors. I mean, some suspicious, somewhat paranoid people suspected that intel was crippling code on AMD processors, but it took a good deal of work to actually demonstrate it.

      That is just one of the many reasons I don't use Intel.

      --
      "Windows is like the faint smell of piss in a subway: it's there, and there's nothing you can do about it." - Charlie Br
    7. Re:Documentation is King by gl4ss · · Score: 1

      well they sort of should be forced to not provide intentionally shitty product to their customers, no?

      I got no qualms about them doing that if they put it in big red letters on the packaging and installer and on the page where you buy/get the compiler ....

      --
      world was created 5 seconds before this post as it is.
    8. Re:Documentation is King by Immerman · · Score: 1

      Who is talking about AMD? We're talking about Intel's surreptitiously anti-competitive behavior as it applies to trusting the efficacy of their compiler - the target of that behavior is irrelevant to the conversation.

      --
      --- Most topics have many sides worth arguing, allow me to take one opposite you.
    9. Re:Documentation is King by Darinbob · · Score: 3, Insightful

      GCC also works with many CPUs that Intel compiler does not. That includes x86 compatible chips from other vendors, as well as the advanced features in Intel chips that were originally introduced by competiting clones. So maybe Intel is nice, but that's irrelevant if you don't even use Intel hardware in your products.

      If Intel really is basing their compiler off of secret architecture documents, then people should be able to deduce what's going on from looking at the generated assembler. Ie, find some goofy generated code that does not seem to make sense given public documents, get a benchmark to compare it, figure out there's a hidden feature, and then make use of it.

    10. Re:Documentation is King by Anonymous Coward · · Score: 0

      That is interesting observation. I used to read documentation but in modern day practice nobody is writing any or they update some in such a way or at the time I do not need it anymore and I am not talking about some small two weeks 3 developers projects where that is not an issue.

    11. Re:Documentation is King by Darinbob · · Score: 1

      And certainly customers are allowed to scream about it all they like if they feel cheated. That behavior is also very clearly an anti-competitive act.

    12. Re:Documentation is King by Anonymous Coward · · Score: 0

      No, they should be forced to not lie about it to people who've paid for an optimizing compiler, not provide one that sabotages their production systems' performance with no warning. Fuck you and your personally dishonest soul.

    13. Re:Documentation is King by Arker · · Score: 1

      "If Intel really is basing their compiler off of secret architecture documents, then people should be able to deduce what's going on from looking at the generated assembler. Ie, find some goofy generated code that does not seem to make sense given public documents, get a benchmark to compare it, figure out there's a hidden feature, and then make use of it."

      In theory, given enough highly skilled eyes checking these things often enough, that is exactly what would happen.

      In reality, who is going to go to that much trouble to do something that actually helps the miscreant here? And more to the point, why try to figure out secret Intel optimizations (and secret optimizations usually wind up being less useful than you think they will be) to make their hardware faster if you are using other hardware? No point at all in that case.

      --
      =-=-=-=-=-=-=-=-=-=-=-=-=-=-
      Friends don't let friends enable ecmascript.
    14. Re:Documentation is King by 0123456 · · Score: 1

      So, uh, how do you expect Intel to know what kind of optimizations will work best on AMD CPUs?

    15. Re:Documentation is King by Wootery · · Score: 0

      Are you not paying attention at all? ICC produced slower, i.e. deliberately sabotaged code-paths for non-Intel chips.

      The design choices made by AMD/VIA/etc don't enter into the equation.

    16. Re:Documentation is King by Anonymous Coward · · Score: 3, Insightful

      If the CPU reports it supports SSE2, and the compiler supports it, I expect it to bloody well use those instructions when told to, not silently produce fucking x87 garbage. Really rocket science apparently.

    17. Re:Documentation is King by Cammi · · Score: 2

      I worked in a place where my whole position was documented over a span of 5 years, PRIOR to me started. It was literally a small binder with the steps to do, with simple If, Then type sequences. Then, beside that binder, was a HUGE fricken binder with all of the "edge cases". That documentation saved my arse plenty of times. Documentation IS King

  2. Not sure why it's troubling. by serviscope_minor · · Score: 5, Insightful

    I don't think it's troubling.

    Firstly they beat on the optimizer a *lot* between major versions.

    Secondly, the compiler does a lot of micro optimizations (e.g. the peephole optimizer) to choose between essentially equivalent snippets. If they change the information about the scheduling and other resources you'd expect that to change a lot.

    Plus I think that quite a few intresting problems such as block ordering are NP-hard. If they change the parameters of their heuristic NP-hard solver, that will give very different outputs too.

    So no, not that bothered, myself.

    --
    SJW n. One who posts facts.
    1. Re:Not sure why it's troubling. by david.emery · · Score: 5, Informative

      Mod parent up +1 insightful.

      Unless you suspect and are trying to debug a code generator error (one of the least pleasant/most difficult debugging experiences I've had), the base assertion that you should understand your compiler's code generation is at best unrealistic, and probably just dumb. Code generation is extremely complex, requiring deep knowledge of both this specific compiler's design and this specific computer's instruction set architecture, how the caches work, pre-fetching approaches, timing dependencies in instruction pipelines, etc, etc. If you do suspect a code generator error, you're best off hiring a compiler expert at least as a consultant, and be prepared for a long hard slog.

      Maybe 30 years ago, for a PDP-8, you could assert that the C code you wrote had some semblance to the generated machine code. That hasn't been true for a very long time, and C++ is most definitely not C in this regard.

    2. Re:Not sure why it's troubling. by zubab13 · · Score: 4, Informative

      Just use something like libsimdpp[1] and you are sure that your code stays vectorized between compiler versions. As a bonus, this and similar wrapper libraries give you an option to produce assembly for multiple instruction sets (say SSE2, AVX and NEON) from the same code. [1]: https://github.com/p12tic/libsimdpp

    3. Re:Not sure why it's troubling. by loufoque · · Score: 0

      I run into codegen errors with various compilers fairly often (surprisingly, not so much with clang, they must have a much better software architecture). They're not that hard to find, and once found, it's not that hard to find why they happen either.
      What is hard, however, is getting the developers to fix it and include the fix in the next release.

    4. Re:Not sure why it's troubling. by loufoque · · Score: 3, Interesting

      Explicit vectorization is indeed much more reliable than automatic vectorization, and it will always deliver better performance.

      Interestingly, there seems to be quite a few abstraction layer libraries for SIMD. There are also at least Boost.SIMD (part of NT2 [1]) and Vc [2].
      Several array-handling libraries (NT2 [1], Eigen [3]) also a leverage SIMD explicitly.
      Alternatively there are plenty of languages based on C with explicit SIMD programming, like the Intel SPMD Compiler [4].

      If you're interested in SIMD, there is also apparently a workshop being held soon on this subject in Orlando [5].

      [1] https://github.com/MetaScale/nt2
      [2] http://code.compeng.uni-frankfurt.de/projects/vc/
      [3] http://eigen.tuxfamily.org/index.php?title=Main_Page
      [4] http://ispc.github.io/
      [5] https://sites.google.com/site/wpmvp2014/

    5. Re:Not sure why it's troubling. by JeffAtl · · Score: 1

      Could you give an example?

    6. Re:Not sure why it's troubling. by loufoque · · Score: 1

      Here is an example in GCC: the optimizer assumes the SSE minps instruction is commutative. It isn't.
      As a result you can get unexpected results depending on the optimizer mood when you call this instruction with a NaN and a non-NaN value.

    7. Re:Not sure why it's troubling. by Anonymous Coward · · Score: 0

      You should have just said you do numbers. Numeric optimizations, especially in floating point, are a perennial locus for bugs.

  3. Very different code by Anonymous Coward · · Score: 4, Interesting

    I have worked on a couple of projects that compiled and ran perfectly with GCC 4.6 and 4.7. They no longer run when compiled with the latest versions of GCC. No warnings, no errors during compilation, they simply crash when run. It's the same source code, so something has changed. The same code, when compiled with multiple versions of Clang, runs perfectly. The GCC developers are doing something different and it is causing problems. Now it may be that a very well hidden bug is lurking in the code and the latest GCC is exposing that in some way, but this code worked perfectly for years under older versions of the compiler so it's been a nasty surprise.

    1. Re:Very different code by david.emery · · Score: 5, Insightful

      Unfortunately, that's not unique to GCC. I've seen this happen with several different compliers for different programming languages over the years. Worse, I've seen it with the same compiler, but different Optimizer settings.

      In one case, our system didn't work (segfaulted) with the optimizer engaged, and didn't meet timing requirements without the optimizer. And the problem wasn't in our code, it was in a commercial product we bought. The compiler vendor, the commercial product vendor (and the developer of that product, not the same company as we bought it from) and our own people spent a year pointing fingers at each other. No one wanted to (a) release source code and then (b) spend the time stepping through things at the instruction level to figure out what was going on.

      And the lesson I learned from this: Any commercial product for which you don't have access to source code is an integration and performance risk.

    2. Re:Very different code by bzipitidoo · · Score: 1

      it may be that a very well hidden bug is lurking in the code and the latest GCC is exposing that in some way

      I have run into this situation. The code actually depended upon a bug in the older gcc versions. When that bug was fixed, the code stopped working. In some cases, the compile failed, in others, it crashed at runtime.

      Specifically, this was around gcc version 2.7, and the bug was this: for (int i=0; i < SIZE; i++) { ... } for (i=0; .... The variable "i" should be out of scope for the 2nd loop and cause an error during compilation, but gcc didn't catch it. gcc version 2.95 caught it. I forget if that bug was fixed in 2.7 or 2.95.

      --
      Intellectual Property is a monopolistic, selfish, and defective concept. It is "tyranny over the mind of man"
    3. Re:Very different code by Anonymous Coward · · Score: 0

      That's the most frustrating thing in CS.

    4. Re:Very different code by Anonymous Coward · · Score: 0

      You may want to check out this bug report: https://bugs.freedesktop.org/show_bug.cgi?id=71116

      Basically, GCC changed instruction ordering a bit to boost performance with out of order executing processors... If your code had undefined behavior similar to the code in that bug report, it may well be the cause.

    5. Re:Very different code by angel'o'sphere · · Score: 1

      It can as well be that you have a subtile memory bug which never really triggered when compile with the old compiler.

      E.g. the latest bug like this, which I encountered.
      something like:
      char[10] data;
      read a file with 10 bites into "data". Assume it is a 0 terminated string.
      Surprisingly that always worked as malloc() handed out chunks devidable by 4, zero initialized. So behind the 10 bytes where 2 more zero bytes.
      Switching to another compiler (more correctly clibrary) made that code crash, but it worked for years before.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    6. Re:Very different code by Gothmolly · · Score: 2

      And trying to do it all yourself is a risk of never getting to market.

      --
      I want to delete my account but Slashdot doesn't allow it.
    7. Re:Very different code by Mr+Z · · Score: 4, Informative

      Actually, the scope of int i changed in C++. Previously, the scope would extend beyond the for. If you enable warnings, G++ will tell you all about it.

    8. Re:Very different code by david.emery · · Score: 4, Insightful

      Well, in part that depends on your market. Most of my work has been in military systems or air traffic systems, where the cost of failure >> lost opportunity cost. That's a point a lot of people forget; not all markets (and therefore the risk calculations for bugs, etc) are created equal.

    9. Re:Very different code by jbcksfrt · · Score: 1

      That was informative, but I would expect that to be caught at compile time. The OP mentioned that he was having runtime errors, I believe.

    10. Re:Very different code by LoRdTAW · · Score: 1
    11. Re:Very different code by drawfour · · Score: 4, Informative

      This is why all code should be compiled with highest warning level enabled, and all warnings should be treated as errors. The compiler can have a very hard time guessing at what you meant, so it's best to be as explicit as you can. If, for some reason, you're positive the code needs to be a certain way that is, and it is correct, you can always use a "pragma warning(disable)" (with appropriate push/pop semantics) to keep your code compiling clean.

    12. Re:Very different code by fulldecent · · Score: 1

      Stop. You are making me feel old, I remember writing code like that. (Which compiled)

      --

      -- I was raised on the command line, bitch

    13. Re:Very different code by PhrostyMcByte · · Score: 3, Insightful

      Your projects were likely doing something which resulted in undefined behavior. It's been extremely rare to have GCC break working standards-compliant code.

    14. Re:Very different code by ebno-10db · · Score: 1

      I used to try to do that, but there are several problems. First, it's non-portable as hell. Second, have you ever tried turning on all the warning options in gcc (and some other compilers)? I'm not sure it's possible to write 10 lines of code that won't generate at least one warning.

    15. Re:Very different code by mark-t · · Score: 1

      Even better, a compiler writer ought not to make a compiler that cannot reliably link separately compiled unoptimized and optimized code such that they will work as they are written to. That is, if a optimization switch is being used that cannot reliably work with separately compiled unoptimized code, then they should not be able to link together in the first place. The compiler/linker should bitch about it even before the program is first run.

    16. Re:Very different code by Anonymous Coward · · Score: 0

      I used to try to do that, but there are several problems. First, it's non-portable as hell. Second, have you ever tried turning on all the warning options in gcc (and some other compilers)? I'm not sure it's possible to write 10 lines of code that won't generate at least one warning.

      All my code is compiled with

          -Wall -Werror -pedantic

      What is the problem writing correct code?

    17. Re:Very different code by Anonymous Coward · · Score: 0

      Even better, a compiler writer ought not to make a compiler that cannot reliably link separately compiled unoptimized and optimized code such that they will work as they are written to. That is, if a optimization switch is being used that cannot reliably work with separately compiled unoptimized code, then they should not be able to link together in the first place. The compiler/linker should bitch about it even before the program is first run.

      How would a compiler know if your code is subject to such restrictions?

      If you don't know what you're doing, don't wander over into the deep side of the pool where programming languages don't hold your pee-pee for you.

    18. Re: Very different code by Anonymous Coward · · Score: 0

      Well that's just bad code fromtwo bad assumptins. And malloc definitel does not zero initialize by design!

    19. Re:Very different code by fatphil · · Score: 1

      Probably your code contains undefinted behaviour. The optimiser has detected a situation which it is completely sure must be true (otherwise there would be undefined behaviour), and optimised something away. When the must-be-true assumption turns out to be false in reality, the code was under no obligation to work, so who cares what happens. Personally I think it's bad QOI to remove significant bits of code as an optimisation based on assumptions about the lack of undefined behaviour without some kind of warning, at least at the higher instrumentation levels. You can't catch everything, but examples like this should be flagged when warning levels are high (but aren't):

      int foo(struct bar_t *baz){
                      quux *quuux = &baz->pquux;
                      if(!baz) { /* can't be true, otherwise the above would be UB */
                                      return -EINVAL; /* so no point even including this whole block */
                      }
                      return make_use_of(quuux); /* may dereference invalid pointer */
      }

      --
      Also FatPhil on SoylentNews, id 863
    20. Re:Very different code by Anonymous Coward · · Score: 1

      You can also use -Wextra to get even more warnings not enabled by -Wall.

    21. Re:Very different code by Anonymous Coward · · Score: 0

      This is not necessarily indicative of a gcc bug. It could very well be (and almost certainly is in fact) that you are relying on undefined behaviour, and the compiler happens to be optimising that undefined behaviour in a different way (that is, it's your bug).

      Of course, this is far from a certainty, so your correct course of action is to reduce the size of your code until you know what it is that causes the crash, and then read the specs until you understand whether it should be compiled the way you think it should be.

    22. Re:Very different code by bzipitidoo · · Score: 1

      The samples of assembler made me feel old! I'm familiar with x86 assembler, and the variations on MOV that go back to the 8086 (things like MOVSB, MOVSW), but this VMOVUPD was totally new to me. But then I have never looked at SSE, or even MMX.

      --
      Intellectual Property is a monopolistic, selfish, and defective concept. It is "tyranny over the mind of man"
    23. Re:Very different code by Anonymous Coward · · Score: 0

      That is your problem right there.
      If you have warnings you are doing something wrong, period. If it won't bite you now, it will bite you on another compiler.

      These days I compile everything with both clang and gcc, and I fix all the warnings. clang also has a static analyser and I also fix all the warnings from that.

    24. Re:Very different code by Anonymous Coward · · Score: 0

      No sh*t. That's what he's saying.

    25. Re:Very different code by Anonymous Coward · · Score: 0

      Try this: -fno-aggressive-loop-optimizations

    26. Re:Very different code by Anonymous Coward · · Score: 1

      But please, don't release with that configuration. There's more than enough software out there where you try to compile it on a recent system and it fails because in newer GCC version something is now a warning that previously wasn't and then you have to read the documentation of the compiler and the build system to find out how to disable this one warning when the only thing you wanted was to compile this damn software.

    27. Re:Very different code by drawfour · · Score: 3, Insightful

      There is a reason for warnings -- it's because you're doing something wrong. Unfortunately, the compiler lets you do it anyway, probably because there is a ton of legacy code that would suddenly "break" if they were errors by default. But that doesn't mean that you should stop trying to fix these issues. Many of these issues only appear to be benign until you stumble upon the exact issue the warning was trying to warn you about. Static code analysis tools are also your friend. That doesn't mean you can blindly trust them -- static analysis tools do have false warnings. But they're way better than inspecting the code yourself. You'll miss something way more times than the analysis tools will give you a false positive.

    28. Re:Very different code by david.emery · · Score: 1

      Mark parent -1 troll.

      That comment just demonstrates you don't know much about these kinds of markets.

    29. Re:Very different code by phantomfive · · Score: 1

      Any commercial product for which you don't have access to source code is an integration and performance risk.

      So true, I've run into the same problem. It doesn't mean you need to only use GPL, but you should try to get the source code when you sign the contract to use the product (you're probably paying enough, anyway).

      --
      "First they came for the slanderers and i said nothing."
    30. Re:Very different code by mark-t · · Score: 1

      Optimization flags could be embedded into the metadata of the output object file from the compilation phase. The linker could then easily determine if optimization flags of two separately compiled units were compatible and refuse to link them if they were not.

    31. Re:Very different code by Immerman · · Score: 1

      Doesn't seem that hard to me. The compiler is making certain assumptions when compiling code with a given set of optimizations. It shouldn't be difficult to determine when those assumptions may affect, for example, memory alignment of data being passed between modules (I'm just guessing that's one of the common culprits). It may not be easy to eliminate those assumptions entirely, but it should be trivial to make a notation in the object file indicating the potentially incompatible assumptions made and list any functions directly impacted by each of those assumptions. Basically any time something is exposed anything through a function interface or externally accessible data you have two choices: make sure all exposed aspects are either deterministically consistent with the standard, or make a note of the inconsistency/non-determinism.

      Once you have that the linker can then check for incompatibilities - any time module A and B are compiled with inconsistent assumptions *and* A accesses affected components of B or vice-versa then you throw a warning, otherwise (like if A only uses simple functions interfaces unaffected by the inconsistencies) you can be reasonably certain there are no optimization-based incompatibilities.

      Even if 99% of the incompatibilities are actually false-positives where the inconsistencies aren't actually relevant that would still be a phenomenal asset in debugging - it makes highlighting potential problem code trivial, and probably rules out at least 90+ percent of the codebase as the source of the problem. And given even fairly unsophisticated code analysis it probably wouldn't be that hard to bring the false-positive rate way down.

      --
      --- Most topics have many sides worth arguing, allow me to take one opposite you.
    32. Re: Very different code by Anonymous Coward · · Score: 1

      And that is lightyears from displaying _all_ warnings.

    33. Re:Very different code by 0123456 · · Score: 3, Informative

      There is a reason for warnings -- it's because you're doing something wrong.

      Uh, no. It's because you're doing something that may be wrong. If it was wrong, the compiler would given an error, not a warning.

      'if ( a = b )' for example. The compiler warns because you probably meant 'if ( a == b )'. But maybe you didn't.

      There's little reason to write such C code on a modern quad-core 3GHz CPU which spends 90% of its time idle and where the compiler will probably generate the same machine code anyway, but that doesn't make it wrong.

    34. Re: Very different code by 0123456 · · Score: 1

      And malloc definitel does not zero initialize by design!

      But, at least early in the program's execution before you start reallocating freed memory, there's a good chance the memory malloc() returns will be zero-filled.

      I seem to remember that debug builds on Windows fill allocated memory with a known pattern for just this reason? Or maybe that was a special hacked version of malloc() that we were using.

    35. Re:Very different code by DickBreath · · Score: 2

      > And trying to do it all yourself is a risk of never getting to market.

      You don't have to maintain the compiler yourself. You just need to have source code to it, and a compiler that compiles it, for the life of your project. That way, if a newer version of the compiler breaks your project, as the original poster complained of, you always have a working compiler for the life of your project. Your compiler may not get any additional improvements. But having it work vs not work is much more important than incremental improvements.

      --

      I'll see your senator, and I'll raise you two judges.
    36. Re:Very different code by Anonymous Coward · · Score: 0

      You must understand the problem is that to the optimizer it is insignificant code; the optimizer cannot tell if such code was intentional by the programmer, placed there via macros (and not intended by the programmer in question), or placed there by the compiler in earlier passes of the optimizer/code generator.

    37. Re:Very different code by Megane · · Score: 1

      If only there was some way you could find out where it crashed, what the generated code looked like, etc. This could be a great way to find bugs in a program. You could call it a Great Detector of Bugs.

      --
      #naabhaprzrag, #sverubfr-000, #agi-fcbafberq, negvpyr[pynff*=' negvpyr-ary-'] { qvfcynl: abar !vzcbegnag; }
    38. Re:Very different code by Immerman · · Score: 1

      Not at all. There's a very big difference between "There was a bug in the compiler which let X slip through until update Y" and "Update Y adheres to new language specifications that make X illegal", even if they look quite similar to a programmer who doesn't follow developments in the language. Can't remember for sure which camp this fell in, but I do remember dealing with the issues for years when moving between compilers that adhered to the old and new standard.

      IIRC under the old standard doing it the new way, redeclaring "i" in each for loop, was actually illegal as it caused multiple declarations of the same variable name. As such your options for portable for loops were pretty much
      1) use distinct iterator names - tedious and potentially confusing, especially in code that lends itself to descriptive single-letter variable names.
      2) pre-declare your iterators so they can be reused by multiple loops
      3) Enclose your entire {for (...) { } } statement within extra { }'s to force iterator new-style scope-limiting under the old standard.

      I used all of them over the years, and they were all sub-optimal.

      Incidentally - did anyone else get into the habit of using "naked" { }'s to scope limit temporary variables for clarity? Sometimes I'll even scope-limit whole blocks of code that could conceptually be spun off into a separate function, at the expense of clarity or significant labor. My rule of thumb - if a "sub-function" would take more parameters than it has lines of code, it's probably not worth spinning off unless it does something tricky and will be called from multiple places. That doesn't mean it's not worth putting some low walls around it though. Madness?

      --
      --- Most topics have many sides worth arguing, allow me to take one opposite you.
    39. Re:Very different code by david.emery · · Score: 1

      "having source code wouldn't have changed anything" Disagree. Particularly at interfaces (e.g. cross-language/cross-compiler calls, APIs to COTS products, etc), sometimes you need to see inside the product to figure out what's failing at the interface. It's nice to talk about omniscient knowledge on the part of product developers, API specifiers (who might not be the same as the API implementers), and customers/users of that API for that product. Our specification techniques are by no means rigorous enough to prevent these kinds of problems.

      "Risk" means just that. It's not a guarantee of failure. Rather it's the possibility of failure, coupled with (multiplied by :-) the consequences of the failure occurring.

      Here's a real-world example, not related to compiler problems per-se, but relevant to your comment:

      We had developed Unix RPC code that worked just fine on several systems, including the commercial product the hardware vendor was proposing. When we got to the installation for test, the code didn't work. After going up to the General Officer/SES level, and across to the vendor senior VP, I was given a copy of the vendor's source code for their RPC library. I was able to step through their code to the actual kernel syscall, and most importantly was able to see the failure value returned by the syscall. (The RPC library took that value, converted it into an ERRNO value of "EACCES", -which didn't tell us -why- the error actually happened.)

      When I saw the value of the syscall, which indicated a non-privileged (not root) process was trying to do something that required 'root' privilege, I was able to go back to the vendor and ask, "Did you implement extra security features for RPC?" After some hemming and hawing, they came back and said, "Yes, you have to be root to install an RPC service." More importantly, that security feature WAS NOT DOCUMENTED. (And I can understand the rationale for saying that only privileged/root accounts can install public RPC services, so this was not an unreasonable restriction, but it was a change from standard practice in Unix systems of the time.)

      This is an example of (a) a situation where the interface failed, even though all of the -code- was correct; (b) the only way I found this was to step through the vendor library to figure out the problem was -missing documentation-.

    40. Re:Very different code by Immerman · · Score: 2

      Easy 99% solution - treat all compiler warnings as errors. A warning means the compiler is having to guess at the proper interpretation of your code because you didn't make it completely unambiguous in the grammar of the language. A different compiler (or version) can thus be reasonably expected to guess differently, changing the behavior of your code.

      --
      --- Most topics have many sides worth arguing, allow me to take one opposite you.
    41. Re:Very different code by Anonymous Coward · · Score: 0

      Speaking about different experiences. I work in a team developing server software which is expected to use up to 80% of CPU capacity at times. I'd say it still makes a little difference.

    42. Re: Very different code by Anonymous Coward · · Score: 0

      Windows zeros unallocated pages of memory when the system idle thread is running, so there if your system has a long uptime there is a good chance your program will malloc zeroed memory.

    43. Re:Very different code by Darinbob · · Score: 1

      Yup, and the commercial product with paid support does not actually get you a fix; in fact they may often tell you that you can upgrade to a later version if you purchase it.

    44. Re:Very different code by Anonymous Coward · · Score: 0

      Portability is not relevant here. You should put a high warning level and pragmas for the compiler you use to DEVELOP, so that you can see well every new warning and decide if you want to change your code or shut up the compiler. It's a good idea to check from time to time with another compiler if you get some extra warning, but then you can ignore the warnings you know come from the places you told gcc to shut up. Now as it happens clang understands and obeys gcc pragmas, so actually gcc pragmas are portable to clang.

    45. Re:Very different code by Darinbob · · Score: 1

      This is typically very rare, because the object modules usually have to conform to an ABI. If unoptimized and optimized modules can not work together then something is breaking the ABI.

      Granted there are sometimes special cases. Ie, on an AVR (8-bit chip) sometimes I want to reserve a global variable in a fixed register, but that requires all modules be compiled with the same flag. But this is explicitly a special case, where the compiler is being told to break the rules.

    46. Re:Very different code by Mr+Z · · Score: 2

      Right, but would your server utilization go from 80% to 90% if you wrote it as two lines?

      a = b;
      if (a) {
      // yadda
      }

      Unless you have an incredibly crappy compiler, the two will generate identical code, but this second version won't give a warning.

    47. Re:Very different code by Darinbob · · Score: 1

      It's not that hard really, if you start from scratch this way. Where it falls down is trying to do this with a large existing product. Also C is trickier here than C++ because C++ has more rigorous rules to begin with.

      For me the hard part with turning all warnings on is not the code developed locally for the project, but the third party libraries that come with source code. Those libraries probably generate 95% of all warnings and red flags in static analysis.

    48. Re:Very different code by Mr+Z · · Score: 1

      I've used naked { } to scope things before. It's actually quite handy. In C, it serves two purposes: It makes sure that this variable's value doesn't intentionally spill into code beyond it, and it gives you a new scope to declare temporaries without having to worry about clobbering some other value you didn't think of. (But, if you're doing things right, then that latter concern should be a lesser concern.) In C++, it also gives you a clear boundary where objects go out of scope that isn't just "by the end of the function."

    49. Re:Very different code by Anonymous Coward · · Score: 0

      Mark parent -1 troll.

      That comment just demonstrates you don't know much about these kinds of markets.

      Mark parent -1 meh and leave grandparent alone. He's right, most government funded sectors have patchy understanding at best of these issues.

    50. Re:Very different code by Darinbob · · Score: 1

      This is a good idea. However sometimes are warnings that should be ignored. Ie, if a function takes 4 parameters in the declaration but the implementation uses only 3 paramters, then GCC will issue a warning. But the API says you need 4 parms so you can't just remove it. So the solution is either to turn off that specific warning (usually means it's off in all files) or add a dummy use case for the parameter, etc, even though there is no bug in the code.

    51. Re:Very different code by Darinbob · · Score: 3, Informative

      Sometimes warnings are false positives as well. Especially when turning warning levels up high they will warn about things that may be indicators of a bug or typo but which actually aren't problems, or in some cases are even intentional. Such as unused variables or parameters; is that a bug or a stylistic choice to not litter the code with extra #ifdef? An unused parameter in general seems an odd thing to complain about, usually the parameter list is fixed in an API or design document whether or not the actual implementation needs all the parameters.

    52. Re:Very different code by Anonymous Coward · · Score: 0

      I used to try to do that, but there are several problems. First, it's non-portable as hell. Second, have you ever tried turning on all the warning options in gcc (and some other compilers)? I'm not sure it's possible to write 10 lines of code that won't generate at least one warning.

      All my code is compiled with

      -Wall -Werror -pedantic

      What is the problem writing correct code?

      Because that's not all the available warnings.

    53. Re:Very different code by Imagix · · Score: 1

      You are just not trying hard enough. I write various commercial products which compile with _no_ warnings. And yes, this is for performance-critical services, and a few hundred thousand lines of code.

    54. Re:Very different code by Imagix · · Score: 1

      Sure there is. Your declaration doesn't match your definition. Bad. Fix it.

    55. Re:Very different code by Darinbob · · Score: 1

      Alignment tends to have problems here too. Small changes in compiled code will place data differently and as soon as it's unaligned the bugs pop up (this really freaks out some programmers who previously only used Wintel and never heard of alignment before). Similarly, buffer overflows as you describe may be perfectly fine until a change in the compiler occurs; it's particularly nasty to track down if it clobbers something on the stack so that the crash doesn't occur until the calling function returns.

    56. Re:Very different code by Imagix · · Score: 1

      Or if you really want to save that 1 line of text:

      if ( ( a == b ) ) {
      // yadda
      }


      Now it's no longer an assignment where a boolean expression is expected, it's an expression where a boolean expression is expected.

    57. Re:Very different code by Immerman · · Score: 1

      Well, first off that's clearly bad code as you point out in the comments - it will result in undefined behavior if baz in null, a situation that's clearly being expected. Granted, it's hard to imagine a scenario outside an extremely naive compiler where that particular undefined behavior is anything other than harmless - well other than this one, where it causes undefined compile-time behavior. I would agree that a warning in such a situation would be nice, in a "we all make stupid mistakes sometimes" kind of way but it would have absolutely nothing to do with optimization. Then again, neither do most errors turned up by dead-code elimination warnings. So yeah, I guess I can see where a "code optimized out of existence" warning would be useful.

      Might be really hard to draw the line so as to not to be swamped in false-positives though, after all a vast field of optimizations rely in skipping behaviors specifically implied by the language. I suppose you might be able to flag all "assume the programmer is competent" based optimization as suspect. I also suspect that level of optimization is happening long after the link to the original code lines has been lost, which would make errors rather vague. Still, even a "roughly two lines of code (15 operations) have been eliminated from foo(...)" could be a godsend in trying to track this kind of thing down.

      Secondly, are their really compilers that would optimize away that if statement? That's actually pretty impressive if not illustrative hyperbole, and might explain a few such "how could this possibly have been causing a problem" headaches I've had in the past.

      Lastly - seems to me a more long-term profitable direction might be to make it more clear to budding programmers that their code is being analyzed and optimized by a pseudo-intelligent machine, and as such they really need to avoid "clever" code like above which may confuse the compiler by exploiting corner-cases of the language. Even if it doesn't result in undefined behavior it's likely going to interfere with optimizations that less "clever" coding would benefit from.

      --
      --- Most topics have many sides worth arguing, allow me to take one opposite you.
    58. Re:Very different code by Mr+Z · · Score: 1

      I think you meant if ( ( a = b ) ), which highlights a different reason this construct is problematic: If you make that error outside the context of a control construct, you'll get a warning about a meaningless computation.

      Your proposed fix isn't really a fix, though. It shuts up GCC, but it doesn't shut up RVCT, for example.

    59. Re:Very different code by Anonymous Coward · · Score: 0

      Suffered something like this on iOS when they added clang. The GCC code compiled and run perfectly, the clang version asserted on impossible stuff (yeah, I know, who writes asserts? must be some crazy bastard who also documents code).

    60. Re:Very different code by drawfour · · Score: 2

      No. Just because something is legal according to the specification does not make it "right". The specification _should_ be restricted, but it cannot because there are a _lot_ of lines of code out there that would suddenly stop compiling. It _IS_ wrong to do 'if (a = b)' for a few reasons:

      1. Someone else won't necessarily know that this was intended unless you have a comment telling them. That comment would take up just as much space as putting an 'a = b;' line before the 'if (a)' line.
      2. If your compiler is not capable of optimizing and figuring out that 'if (a=b)' and 'a=b; if (a)' should generate the same machine code, then your compiler is a piece of crap and should be upgraded or replaced.
      3. If you get in the habit of doing those kind of 'shortcuts', you are more likely to accidentally do the wrong thing. And since you're so used to that kind of programming, you're more likely to miss it when trying to track down the bug that you introduced. If 'if (a = b)' just looks wrong to you because you never use it, it is more likely to jump out at you when you're debugging, whether it's your own code or someone else's.

      The same thing is true for casting ints to pointers, having fall-throughs in switch statements, signed/unsigned mismatches, and a myriad of other "legal" but "just-as-wrong" things.

    61. Re:Very different code by Imagix · · Score: 1

      Yep... and highlights why I don't even try to use an assignment in that area (both that a certain complier will still warn about it, and that it even gives rise to this problem. Just write the assignment before the test and be done with it.). Whether RVCT should or should not complain about it is a QoI (Quality of Implementation) issue.

    62. Re:Very different code by Arker · · Score: 1

      "'if ( a = b )' for example. The compiler warns because you probably meant 'if ( a == b )'. But maybe you didn't."

      If you did not, then you should have written something like a=b;if b {... instead. It may be technically legal code but it's very bad and it should be flagged and warned, you are just being cute at the expense of readability and even you probably wont remember what the heck you did there 6 months later when you look at the code again.

      --
      =-=-=-=-=-=-=-=-=-=-=-=-=-=-
      Friends don't let friends enable ecmascript.
    63. Re:Very different code by Anonymous Coward · · Score: 0

      >(usually means it's off in all files)'
      bitches don't know about my http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html

    64. Re:Very different code by Immerman · · Score: 2

      Quite true about C++. I've used it to good effect in conjunction with "active" objects whose creation and destruction can encapsulate much of their functionality - things like thread locks, at the simple end.

      --
      --- Most topics have many sides worth arguing, allow me to take one opposite you.
    65. Re:Very different code by vux984 · · Score: 1

      Sure there is. Your declaration doesn't match your definition. Bad. Fix it.

      I think you missed something there. The declaration and definition would match, but he doesn't use one of the parameters.

      While there are quite a few ways to "fix" this; I'm honestly not sure what the best is.

    66. Re: Very different code by EvanED · · Score: 1

      The Windows ZPT doesn't affect what your uninitialized-malloc region will contain: I'm 98% sure that all reasonable (non-embedded) OSs zero pages before they map them into a process's memory space for security reasons. The ZPT only means that there is usually a pool of pre-zeroed pages sitting around, and so it doesn't have to go clear one out on demand. (I also don't know what happens on Linux in terms of whether it does this in the background or not.)

    67. Re:Very different code by Rhacman · · Score: 1

      That's not what Darinbob is saying. Both the declaration and the definition of the function take 4 parameters as mandated by the API he is writing to. In his particular instance, however, he does not care what the value the caller passes to one of the parameters. This is common with things like callback routines / event handlers. Often the callback API provides you with information that you don't need for your specific implementation.

      I still recommend compiling clean with -Wall but it does mean that there will be times where code is already correct but you need to add something just to tell / trick the compiler into not emitting the warning.

      --
      Account -> Discussions -> Disable Sigs
    68. Re:Very different code by Anonymous Coward · · Score: 0

      Or remove the name from the parameter in the definition, if you are not using it.

      void foo(int a, int, int c)
      {
      }

      Or even comment it out to be explicit about it,

      void foo(int a, int /*b*/, int c)
      {
      }

      I've learned that if you really need warning about something that is not implemented, then add a warning as part of unit tests.

      Qt has a specific macro to handle this case too, if you want to not do any of the above. No code generation, and no warning and very explicit source code that the parameter is there, but unused.


      #if defined(Q_CC_INTEL) && !defined(Q_OS_WIN) || defined(Q_CC_RVCT)
      template <typename T>
      inline void qUnused(T &x) { (void)x; }
      # define Q_UNUSED(x) qUnused(x);
      #else
      # define Q_UNUSED(x) (void)x;
      #endif

      then you have,

      void foo(int a, int b, int c)
      {
              Q_UNUSED(b) ...
      }

    69. Re:Very different code by EvanED · · Score: 1

      Secondly, are their really compilers that would optimize away that if statement?

      Probably. Here's an even more impressive example.

    70. Re:Very different code by Imagix · · Score: 1

      Don't give the 4th parameter a name. You can just specify the type.

    71. Re:Very different code by EvanED · · Score: 1

      So the solution is either to turn off that specific warning (usually means it's off in all files)...

      Just a note: recent versions of GCC have (finally) gotten the ability to enable and disable many warnings for regions of code through the #pragma diagnostic.

      ...or add a dummy use case for the parameter

      So you add (void)param;. Big whoop. What's worse, typing a few extraneous keystrokes, or spending an hour debugging something elsewhere that the compiler could have told you about?

      (Or, possibly even better, you define an UNUSED_PARAM macro and then write foo(int x, int UNUSED_PARAM(y)) or similar. On MSVC, UNUSED_PARAM(a) expands to nothing, and on GCC-compatibile compilers it expands to a __attribute__((unused)) or something like that. That won't work everywhere though, but if you're in the realm of desktop software it will probably work well enough.)

      In my firm opinion, it's almost always better to change your code slightly to eliminate the more common warnings (e.g. -Wall, though I also like -Wextra) than it is to disable the warnings because they are too noisy.

    72. Re:Very different code by ebno-10db · · Score: 1

      You should put a high warning level and pragmas for the compiler you use to DEVELOP, so that you can see well every new warning and decide if you want to change your code or shut up the compiler.

      That's fine if you use gcc or clang, because they do a good job of analyzing the code to decide if a warning is warranted. I like to use -Wall, and sometimes a few others. It's a whole different story if you use proprietary compilers for embedded work, many of which spit out warnings for no reason or fail to spit out warning when they should.

    73. Re:Very different code by Anonymous Coward · · Score: 0

      My solution of choice is to just put a line casting the parameter to void (or void * if it's a pointer). I've seen people make a macro specifically for that and call it UNUSED_PARAM or something, so that you have

      int foo(int bar, int baz)
      {
              UNUSED_PARAM(baz);
              return bar + 2;
      }

      Since it's a statement without effect, the compiler will probably optimize it away, and the pointer version handles NULL correctly. It's about as clear as anything can be, and (importantly) it's completely standard, as opposed to compiler extensions like GCC's unused or such.

      Honestly, I think such a solution is better than the alternative, because looking at a function that simply fails to use its arguments makes you wonder things like "How long has it been like this?" and "Is this code half-refactored and in a broken state? Are there logical problems somewhere?" You could put such in as a comment, as well, but this has the benefit of allowing you to keep -Wall -pedantic, which as mentioned above is a great target to shoot for if there's any possibility of reaching it.

    74. Re:Very different code by EvanED · · Score: 1

      Or remove the name from the parameter in the definition, if you are not using it.

      That's not legal in C, at least through C99. (I actually thought it wasn't in C++ either, but apparently it is.)

    75. Re:Very different code by ebno-10db · · Score: 1

      These days I compile everything with both clang and gcc, and I fix all the warnings

      I do the same thing when I have the pleasure of using gcc. One of the things I like about it is the quality of the warnings. Other compilers I have to use, typically proprietary compilers for embedded work, are not so good.

      If you have warnings you are doing something wrong, period.

      Then they should be errors. Yes, I know about -Werror on gcc but the problem is that there is no standard for warnings. What's clean on one compiler gives warnings on another, and vice versa.

      The real bottom line is that if you want to do that level of anal retentive checking (and I'm a big fan of it) then you shouldn't be using C/C++. Try a language that was designed from the ground up for strong static checking, like Ada. I know you usually don't have that choice, but the point is that the language itself is the root of the problem.

      BTW, in Ada if you really need to do something that would normally give you an error, you usually can but you have to mark it with a pragma or use a library function that includes "unsafe" as part of its name. That's a pretty clear indication that you should triple check that part of the code. You can also setup compiler switches or just grep to find all the unsafe stuff.

    76. Re:Very different code by Anonymous Coward · · Score: 0

      I disagree with treating treating warnings as errors, but I do agree warnings should raise eyebrows and not be left alone. The problem with -Werror is it forces you to address those warnings now. In the earlier development stages the code will be changing substantially before release, so avoiding tackling harmless warnings is a noticeable benefit. Once you're near release, stamping out warnings is a Good Thing(tm).

    77. Re:Very different code by loufoque · · Score: 2

      Most likely, you were just invoking undefined behaviour.
      GCC 4.8 has new optimizations tied to signed integer overflow, for example. a+b is the same in hardware regardless of whether the inputs are signed or not (assuming two's complement hardware), but to the compiler, that's not the case.

    78. Re:Very different code by loufoque · · Score: 1

      That's why you don't buy software without support.
      With support, they'd be contractually obliged to debug it.

    79. Re:Very different code by loufoque · · Score: 1

      I wouldn't say extremely rare. It depends entirely of what you are doing.
      Some parts of the compiler are more stable than others.

      Advanced C++ and gcc-specific extensions are two things that can break from time to time. Combine the two together, and running into bugs isn't so rare.

    80. Re:Very different code by jthill · · Score: 1

      So write a dumb little 10-liner to generate potentially-failing option combinations, with any luck it's just one or two of the ones enabled by the next level up from the lowest working `-On`.

      --
      As always, all IMO. Insert "I think" everywhere grammatically possible.
    81. Re:Very different code by Darinbob · · Score: 1

      Actually it's not that portable, though that's only with some compilers.

      Bigger problem is that the parameter actually is used, but only in some builds, because there's an #ifdef in the function. This also happens sometimes with variables, because in C you have to declare the variable up at the top to be portable, whereas the code that uses it may be at the bottom of the function, so the programmers often just use the #ifdef at the point of use without an #ifdef at the declaration.

      I had started using things like an UNUSED parameter, but there were so many instances of this in the project that I gave up on it and disabled that warning instead. There are also things such as GCC __attribute__ but that's not portable. It is on my list to get rid of the -Wno-unused-parameter flag, but that's not on my primary list of development goals so it's a part time effort to increase level of compiler warnings.

      Another snag I hit is that the method to "use" a variable to avoid the warning isn't clear. In some compilers just doing "a = a;" will work, but other compilers or compiler versions will issue warnings on that code ("variable set but not used"). The portable way seems to be to typecast it to void, as in "(void)a;". I went and rewrote a lot of other programmers' fixes to this warning so that it would continue to work in a later compiler version.

      And of course, the majority of these warnings often come from third party libraries that come as source, many of which are riddled throughout with #ifdefs for the various options they provide or architectures they support.

    82. Re:Very different code by Darinbob · · Score: 1

      GCC warns about unrecognized pragmas as well. So to use that new pragma you either need to #ifdef it, or make sure the entire programming team, QA, and build, all swap over to the new compiler at the same time.

      Of course adding this stuff is not that bad when you are writing code from scratch or on a new project. It makes a great deal of sense to make sure all new projects begin life with warnings turned up to the max. However when the project is many years old and you've got third party libraries to compile as well, it can be an enormous amount of work to fix up all the warnings after the fact. It's something I do during the infrequent periods between emergencies.

      (Hint, never let programmers under 25 or hardware engineers develop your coding standards or your initial code base, because you'll be stuck with their naive result for years. But that's the nature of start ups, no one has time to slow down and do things right until the problem has grown out of control.)

    83. Re:Very different code by Anonymuous+Coward · · Score: 1

      So the solution is either to turn off that specific warning (usually means it's off in all files)

      why?

      It's very easy to tailor compiler options for each source file in the Makefile.

      There's also 'pragma GCC diagnostic push/pop', even if it doesn't work for some cases (like -Wunused-function).

      For unused functions/variables/parameters it's best to conditionally define 'UNUSED__' to '__attribute__((unused))' for gcc and use that; creating dummy use cases is stupid.

    84. Re:Very different code by david.emery · · Score: 1

      We bought support. But to get support from organization X, that organization has to first admit it is -their problem-. Please re-read my post to see that no organization wanted to take ownership of the problem.

    85. Re:Very different code by loufoque · · Score: 1

      Depending on the support contract you negotiated with them, they shouldn't need to admit it.
      I recommend you tell management to improve their legal department.

    86. Re:Very different code by jthill · · Score: 1

      In particular notice the example at "Interacting Compiler Optimizations Lead to Surprising Results", it's an exact match for GGGP. Tests that are redundant in context is a *very* common result of inlining, compilers these days optimize based on propagating deduced range constraints, which can wind up stripping huge amounts of dead code -- calling a safe function twice in a row, for instance, error checks on any repeated arguments are often wasted, freeing up branch-prediction slots and cache lines and load-store bandwidth for prefetching that's now on a guaranteed path ... and how is an optimizer to tell whether a test being irrelevant signifies a fatal flaw or trust that dead-code-elimination can clean up properly?

      --
      As always, all IMO. Insert "I think" everywhere grammatically possible.
    87. Re:Very different code by david.emery · · Score: 1

      Obviously you believe you're more qualified in contract law than the lawyers who were involved. Good on you.

    88. Re:Very different code by Immerman · · Score: 1

      Yowza, I wish I had read that years ago, It might have saved me some serious headaches. The "contains_null_check" was interesting to watch the mechanism in action, but the undefined behavior was obvious. The next though... ouch. I followed the link to part 1 and had no idea so very many common things were actually classified as "undefined". I mean integer addition overflow? *Everyone* exploits that occasionally.

      In a world where "undefined behavior" means "the extremely aggressive compiler can assume there's nothing clever going on" *every* programmer should have as near a comprehensive list of undefined behaviors as possible on hand as things to never, ever let anywhere near flow control.

      --
      --- Most topics have many sides worth arguing, allow me to take one opposite you.
    89. Re:Very different code by Anonymous Coward · · Score: 0

      #define UNUSED_PARAMETER(x) (void)x

      .
      .
      .

      int fnord(int xyzzy, int plugh) {
              UNUSED_PARAMETER(plugh); ....
              return xyzzy;
      }

      Or something like that. You can then have some #ifdef magic to make the UNUSED_PARAMETER() macro work differently depending on the compilation context, using cast to void, x = x, or whatever floats the compiler’s boat.

    90. Re:Very different code by loufoque · · Score: 1

      IANAL (I'm an entrepreneur who has been a subcontractor and has subcontracted in the software business), but I know that you can pretty much set the terms you want on a contract. In particular, you can ask that an incident you file to a subcontractor is investigated by said subcontractor in a given time frame.

      In truth, it is up to the buyer and the seller to negotiate the terms of the contract, the lawyers are just there to advise both parties.
      The seller can agree to provide minimal service for a minimal price, but the buyer can ask for better service, which he will probably have to pay extra for.

    91. Re:Very different code by Grishnakh · · Score: 1

      This also happens sometimes with variables, because in C you have to declare the variable up at the top to be portable, whereas the code that uses it may be at the bottom of the function, so the programmers often just use the #ifdef at the point of use without an #ifdef at the declaration.

      In C, this is true. If it's C++, you can declare the variable at (or nearer to) the point of use, which handily avoids this problem.

      I had started using things like an UNUSED parameter, but there were so many instances of this in the project that I gave up on it and disabled that warning instead. There are also things such as GCC __attribute__ but that's not portable.

      It doesn't need to be. You can set up an UNUSED macro which uses non-portable methods, depending on the compiler used. Here's one I found somewhere which I use to avoid this warning:

      // suppress warnings for unused arguments
      #ifdef UNUSED
      #elif defined(__GNUC__)
      # define UNUSED(x) x __attribute__((unused))
      #elif defined(__LCLINT__)
      # define UNUSED(x) /*@unused@*/ x
      #else
      # define UNUSED(x) x
      #endif // example: void dcc_mon_siginfo_handler(int UNUSED(whatsig))

      And of course, the majority of these warnings often come from third party libraries that come as source, many of which are riddled throughout with #ifdefs for the various options they provide or architectures they support.

      That's the problem I've found. You can add stuff like the above to avoid warnings in your own code, but if you're #including a library from somewhere else, you're stuck with whatever's in there, and turning on extra warnings can give you loads of warnings for things you have no power to fix. I wonder if there's some kind of compiler option to ignore warnings in third-party libraries?

    92. Re:Very different code by Anonymous Coward · · Score: 0

      > 'if ( a = b )' for example. The compiler warns because you probably meant 'if ( a == b )'. But maybe you didn't.

      The only way "if (a = b) ..." would ever pass code review in any competent shop would be a directive from a major deity (no demigods) inscribed on a stone tablet in flaming letters.

    93. Re:Very different code by Ottibus · · Score: 1

      All my code is compiled with

          -Wall -Werror -pedantic

      What is the problem writing correct code?

      There is nothing wrong with writing correct code, but I would not use gcc warnings as a way of defining what is and is not correct code. In fact code that generates a warning is (by definition) correct, otherwise it would generate an error.

      There is a problem with using "-Werror" because you cannot predict what code is going to generate warnings in future versions of the compiler or with different processor architectures. This may not be an issue for personal projects, but it can be a real pain when used on a large, long-running code base.

    94. Re:Very different code by GuB-42 · · Score: 1

      No, the specs shouldn't be restricted for style reasons. I believe that the permissive specs and "undefined behaviors" are part of what made C and later C++ so successful.
      I hate it when languages try to dictate how I should code when there are no technical reasons. My beliefs are that languages should be designed for experts, not for preventing beginners from shooting themselves in the foot. For this, there are compiler warnings, coding standards, static analysis tools, ... (which I believe are essential)

      Now let me tell you a few reasons why "if (a = b)" is better than "a = b;" followed by "if (a)" :
      - An extra line takes up screen real estate, which is precious.
      - In the two line version, "a" is written twice instead of once. It goes against the principle of code factorization.
      Of course there are arguments going against it but it is just to show that it is not clear cut. Personally, I would use "if ((a = b))" : it gets rid of the warning, it's a common way of showing that you are not doing a typical equality test and it doesn't suffer the problems I mentioned.

      As for point 2, while it is unlikely to find a compiler that have trouble guessing that the two styles mean the same thing, changing compiler is not that simple, especially if you are on an exotic platform.

      I also don't believe in point 3 : whether you use it of not, "if (a = b)" remains uncommon, and it will jump at any experienced programmer.

    95. Re:Very different code by Valdrax · · Score: 1

      How would spending the time to look through the source code themselves have been more of a waste than spending a year fighting with a recalcitrant vendor?

      The best solution is to have access to the source code AND a dev team that is actively developing it that you can submit bugs to. If they are willing to spend the time to fix it, then that's great. If they aren't, then at least you have recourse. Also, you have greater ability to prove it IS their fault and that they do need to fix it themselves.

      It's not like having access to the code is mutually exclusive with having support.

      --
      If it's for-profit but free, you're not the customer -- you're the product (e.g., the Slashdot Beta's "audience").
    96. Re:Very different code by Yunzil · · Score: 1

      . Now it may be that a very well hidden bug is lurking in the code and the latest GCC is exposing that in some way, but this code worked perfectly for years under older versions of the compiler so it's been a nasty surprise.

      Could be this. At my last job we had some third-party code that worked fine with everything up to gcc 4.1.2. When some people in the group started using 4.4 the code in question went into an infinite loop, but only when compiled with optimization on. I eventually traced the problem to comparing two floats with the '==' operator (IIRC), which is a no-no, but worked anyway until the gcc people changed something in the optimizer.

    97. Re:Very different code by Yunzil · · Score: 1

      Such as unused variables or parameters; is that a bug or a stylistic choice to not litter the code with extra #ifdef?

      It's not a bug, but it's sloppy and lazy.

    98. Re:Very different code by OneAhead · · Score: 1

      Valgrind (or more specifically memcheck) is your friend. This kind of stuff is almost always a latent memory error that starts wreaking havoc when the "offending" compiler organizes memory slightly differently. Almost.

    99. Re: Very different code by OneAhead · · Score: 1

      Well duh! GP did call it a bug, didn't he?

    100. Re:Very different code by Anonymous Coward · · Score: 0

      Congratulations, you just created a possible race condition.
      "if((a=b))..." is equivalent to "a=b;if(a)..." *not* "a=b;if(b)..."

    101. Re:Very different code by david_thornley · · Score: 1

      In that case, the compiler is complaining about code that looks wrong, which I think perfectly legitimate. Put parentheses around the "a = b" if nothing else. Give the next poor sap (possibly you in a year) a fighting chance to realize this is not a typo.

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    102. Re:Very different code by toddestan · · Score: 1

      That's not the case with a lot of warnings. Most warnings are for perfectly valid code, where the behavior of said code is well defined and any compiler should produce the same program. The warnings are there because the compiler thinks you may have intended something different than what the code states.

    103. Re:Very different code by Immerman · · Score: 1

      Fair enough, forgot about those. However in almost every case they're highlighting the opposite problem - you are doing something "clever" that is commonly evoked by accident in "normal" code, in which case you should probably really consider making your code a little more "normal" anyway, if only out of courtesy for whoever may be trying to modify it in a few years. Make it so they can easily tell that the "abnormal" behavior is in fact intended, as well as letting them quickly skim the code without misinterpreting the code as doing the "normal" thing.

      As an added bonus you will now be defended from your own accidental invocations by the compiler's warnings.

      Or, if you're really attached to your clever usage pattern, just disable that specific warning, but leave all the others as things to be fixed. I'll tell you I resisted for years, but I've had enough "well THAT would have made for an obscure bug" moments that I (mostly) try to fix any warnings I get.

      --
      --- Most topics have many sides worth arguing, allow me to take one opposite you.
  4. Once I just changed just one line by deodiaus2 · · Score: 2

    And got completely different results!

    1. Re:Once I just changed just one line by Anonymous Coward · · Score: 1

      -return FALSE;
      +return TRUE;

  5. News for nerds or not by symbolset · · Score: 5, Informative

    Asking any audience larger than about 20 to compare the qualitative differences of object code vectorization is statistically problematic as the survey group is larger than the qualified population.

    --
    Help stamp out iliturcy.
    1. Re:News for nerds or not by Anonymous Coward · · Score: 0

      You are absolutely spot on. Back in "the day" when I was learning about computers, we did build kit 8080a machines and hand built add on memory expansion for them (on breadboards), etc. We had to create programs for them to do things like control model train switches, etc. - in assembler of course - and these things only had the most basic of interfaces (an LED display and a 24 key keyboard with hex input, a store, recall, and run key). Even then I wouldn't have been any good at "optimizing". We just wrote some assembler that worked and called it done. After that I hacked a bit of assembly on a Commodore VIC-20 - it was just a simple text editor. Since then it has been high level languages with no in-line assembler. I wouldn't have the first clue what to look at in checking the output of my compiler. I write high level code and the compiler does its job and creates something that can run on the OS / hardware. End of story.

    2. Re:News for nerds or not by Mr+Z · · Score: 2

      Also notably absent were any performance benchmarks. Two pieces of code might look very different but perform identically, while two others that look very similar could have very different performance. In any case, you should be able to work back to an achieved FLOPS number, for example, to understand quantitatively what the compiler achieved. You might have the most vectorific code in existence, but if it's a cache pig, it'll perform like a Ferrari stuck in mud.

    3. Re:News for nerds or not by fulldecent · · Score: 1

      sudo mod parent up

      --

      -- I was raised on the command line, bitch

    4. Re:News for nerds or not by jbcksfrt · · Score: 2

      Boo this man!!! :-) I was happy to see something that only nerds would care about on Slashdot, rather than politics and BS about Bitcoin.

    5. Re:News for nerds or not by Anonymous Coward · · Score: 0

      and I thought this was the NSA/Snowden site.

    6. Re:News for nerds or not by Anonymous Coward · · Score: 0

      Only if the NSA made their office building out of a 3D printer.

    7. Re:News for nerds or not by loufoque · · Score: 1

      Why are you counting in FLOPS in the first place? Use a real unit.
      Cache is independent from vectorization. While both affect the performance of the code, when evaluating the performance of vectorization on its own only how many cycles the computation would take if all data were in L1 cache is considered.

    8. Re:News for nerds or not by Guspaz · · Score: 1

      Considering that Cogswell's previous works include a bunch of completely useless compiler benchmarks that tell you how fast the *compiler* produced the code, and now how fast the resulting code was... I don't think we should be surprised that he's produced another useless article.

      When I use a compiler, I don't really care what the assembly it produces look like, I care about how it performs.

    9. Re:News for nerds or not by Mr+Z · · Score: 1

      How is Floating Point Operations Per Second not a real unit? It measures amount of floating point computation performed in a unit of time. I can compute the theoretical peak FLOPS for a given architecture by multiplying the number of computational units by the clock rate. I can compute the achieved FLOPS for an algorithm by dividing the total work performed by the time taken. The ratio of achieved rate to theoretical peak even gives me a measure of efficiency, so I know what's performing well and what isn't.

      And, I would argue that cache is extremely important when considering vectorization, especially when considering loop nests. I might get much more impressive vectorization if I execute a loop nest in a particular order. But, if I get better cache locality by interchanging two loops, I may see much better performance in the second case. Matrix multiply is a poster child for this.

      So if you're looking at the output of the compiler's optimizer and saying "compiler A is better than compiler B at vectorizing" looking only at the instruction sequence, and ignoring the actual memory access pattern and the effects of the cache, you might draw the wrong conclusion. The optimizer may have made other transformations to help the cache that have the effect of throttling vectorization, but result in better overall code. I recall seeing elsewhere that Intel's compiler is more aggressive about reordering loop nests to help out the cache, for example. When that happens, it might look like the Intel compiler didn't vectorize nearly as aggressively as another compiler, when that's not really what's at play.

    10. Re:News for nerds or not by loufoque · · Score: 1

      How is Floating Point Operations Per Second not a real unit?

      Because 1) not all operations are equal and 2) the clock rate isn't constant.
      It's not a very useful information, unless what you really want to count is the amount of data treated by second, which is better addressed by a simple B/s bandwidth unit.

      And, I would argue that cache is extremely important when considering vectorization, especially when considering loop nests. I might get much more impressive vectorization if I execute a loop nest in a particular order. But, if I get better cache locality by interchanging two loops, I may see much better performance in the second case. Matrix multiply is a poster child for this.

      So if you're looking at the output of the compiler's optimizer and saying "compiler A is better than compiler B at vectorizing" looking only at the instruction sequence, and ignoring the actual memory access pattern and the effects of the cache, you might draw the wrong conclusion.

      Cache is of course of utmost importance for performance, but you fail to see it's a different problem entirely. Vectorization happens at a different level.
      I don't know what world you live in, but no optimizer of any C compiler changes the memory access pattern of your code. If your code is bad from that point of view, there is nothing it can do, only the developer can optimize that. What the compiler can do is schedule your instructions better so as to fill the pipeline to the maximum while trying to minimize register usage, taking into account the fact that scalar and simd use different registers and pipelines (though if you want that to be done well, you're better off doing that by hand while reading the processor specs).
      AFAIK the only negative effects compiler optimizations can have on the cache is that they can generate code bloat by unrolling or inlining too much. That's unlikely to prevent any vectorization though. Conservative inlining or unrolling policies in the middle-end can however prevent vectorization because they don't take into account the gains associated to switching to the simd ISA.

    11. Re:News for nerds or not by Mr+Z · · Score: 1

      I don't know what world you live in. Nearly every modern C compiler majorly reorders memory accesses when optimization is enabled. Reordering memory accesses is part of what the new restrict keyword is about, after all. The volatile keyword is there to prevent the compiler from reordering or eliminating memory access.

      Vectorized memory accesses nearly always implies reordered memory access.

      Consider a simple memory copy: for (i = 0; i As long as dst and src do not overlap, you can vectorize this code. But, that implies reading N elements of src before writing N elements of dst. I don't know how you define reordered memory access, but that looks like reordered memory accesses to me.

      Ok, I hear you shouting "That's not what I meant! I meant it still accesses array a in the same order before and after, and likewise for b!" Well, that's just a trivial example. I've worked with C compilers that interchange loop levels, unroll outerloops and jam the inner loops together, etc. Such compilers are more the rule than the exception these days.

      So, I call BS on this bald, false statement of yours: "no optimizer of any C compiler changes the memory access pattern of your code." That pretty much hasn't been true since nearly the beginning. Even just having a register allocator changes the memory access pattern of your code, not to mention instruction scheduling, etc. But it's especially true these days. Google "loop interchange", "loop fusion", "loop tiling", "loop distribution", etc. You might be surprised what compilers might do to your code.

    12. Re:News for nerds or not by Mr+Z · · Score: 1

      Ugh... should have previewed. That third paragraph should read:

      Consider a simple memory copy: for (i = 0; i < len; i++) dst[i] = src[i]; As long as dst and src do not overlap, you can vectorize this code. But, that implies reading N elements of src before writing N elements of dst. I don't know how you define reordered memory access, but that looks like reordered memory accesses to me.

    13. Re:News for nerds or not by Mr+Z · · Score: 1

      If you want to learn more about the state of the art, you might start here. It'll catch you up to where we were 20 years ago.

    14. Re:News for nerds or not by loufoque · · Score: 1

      Sorry, but in your example the fact that dst and src overlap or not is irrelevant for vectorization. Even for dst[i+j] = src[i] with j small enough it's irrelevant too.
      Sure, vectorization and other optimizations change memory access ordering (loadx4 computex4 storex4 instead of (load compute store)x4), but I was talking about the pattern, which doesn't change.

    15. Re:News for nerds or not by loufoque · · Score: 1

      Compiler authors and researchers like to claim their software performs all kinds of optimizations automatically. I remember being told of a conference not so long ago where a colleague explained several transformations he did to his C code of a simple filter algorithm that multiplied performance by several levels of magnitude on POWER, and an IBM guy said their compiler should take care of all those transformations automatically. Well clearly, it didn't.

      I'm quite aware of the state of the art, I have in particular seen the work of the researchers who worked on the polyhedric model for loop optimization which was relatively recently added to llvm and gcc. It can indeed do tiling or loop fusion, or even split your loops in several ones to identify the parallel sections, assuming you have full alias analysis information, your loops have simple boundaries and regular control flow, and you have enough time to find that this is the right transformation to make among the whole space of possible transformations.

      I also know that in the real world, it doesn't work so well unless you explicitly program for it or guide it with pragmas. Automatic vectorization isn't reliable, compilers even fail at unrolling most of the time. Why would you rely on much more complex transformations to occur magically?

    16. Re:News for nerds or not by Mr+Z · · Score: 1

      So did you read the two paragraphs that followed? And in case you think I'm imagining these compilers, flip to PDF page 129 (page 119 in the text) and see:

      High-level optimizations (HLO) exploit the properties of source code constructs, such as loops and arrays, in the applications developed in high-level programming languages, such as C++. They include loop interchange, loop fusion, loop unrolling, loop distribution, unroll-and-jam, blocking, data prefetch, scalar replacement, data layout optimizations, and others. The option that turns on the high-level optimizations is -O3.

      The optimizations I highlighted all will affect the data access pattern, especially loop interchange, blocking and data layout optimization. Next, check the date on the document: 2003. That's a decade ago. It's reasonable to expect they've only gotten more aggressive since then.

      This much shorter survey of modern compilers also goes into optimizations that might change access order. They even call this reordering out: "Since loop interchanging may change the access pattern, care must be taken to not introduce non-unit stride access."

      Welcome to modern compilers.

    17. Re:News for nerds or not by Mr+Z · · Score: 1

      Ok, you know all this, and yet claim that "no compiler does this." That's rather a different claim than "In practice, it doesn't happen as often as one would like."

    18. Re:News for nerds or not by loufoque · · Score: 1

      The optimizations I highlighted all will affect the data access pattern

      That's not quite true. Only some of the highlighted ones will, the others keep the same general pattern (unrolling in particular, which isn't so high level).

      As I said in another part of the thread, those high level transformations you speak of don't really happen in the real world, and are not reliable (hence the "I don't know what world you live in"). Compiler authors can claim all they want, but having done a lot of looking at assembly and optimizing manually, I can tell you it's still quite far from what an expert can do. With the Intel compiler, I've even had issues with scalar replacement as soon as you have enough object encapsulation.

  6. Re:I Agree! by Anonymous Coward · · Score: 0

    that is a weird-ass troll (the link is a video of chiptune synthesized pop stars)

  7. Vectorized factorials! by Mr+Z · · Score: 4, Interesting

    One amusing thing I discovered is that GCC 4.8.0 will actually unroll and vectorize this simple factorial function: Just look at that output!

    1. Re:Vectorized factorials! by DickBreath · · Score: 4, Funny


      Here is how I do a factorial function. No recursion, no loops, no vectorization needed. It's in Java. Converting this basic idea to C is left as an exercise for advanced readers.

              static public long factorial( int n ) {
                      switch( n ) {
                              case 0:
                              case 1: return 1L;
                              case 2: return 2L;
                              case 3: return 6L;
      . . . cases 4 to 18 omitted to bypass slashdot filters . . .
                              case 19: return 121645100408832000L;
                              case 20: return 2432902008176640000L;
                      }
                      return 0L;
              }

      --

      I'll see your senator, and I'll raise you two judges.
    2. Re:Vectorized factorials! by Mr+Z · · Score: 3, Informative

      Why isn't that just a lookup table? My point in mentioning factorial is that there's no point in vectorizing that thing. Even a simple loop would be small compared to the cost of a single L2 cache miss.

    3. Re:Vectorized factorials! by loufoque · · Score: 1

      Is that some sort of joke? Surely you can tell this is not the optimal assembly code at all.

    4. Re:Vectorized factorials! by DickBreath · · Score: 1

      It basically *is* a lookup table that covers all possible values, but I wrote it a long time ago. (Hence why it returns 0L for non-sane inputs instead of throwing an exception.) A switch() is a lookup table. I could have used a public final static array and done my own bounds checking.

      --

      I'll see your senator, and I'll raise you two judges.
    5. Re:Vectorized factorials! by Mr+Z · · Score: 1

      Interestingly, GCC 4.8 actually replaces that switch/case with a lookup table. On older GCCs and with compilers for other platforms, the switch-case is an order of magnitude slower or worse, as it actually resulted in branches. And `switch-case` branches are sometimes very difficult to predict, depending on the hardware branch predictor and the code around it.

      It appears GCC has an "unswitch" optimization that handles a switch-case used in this way.

    6. Re:Vectorized factorials! by Mr+Z · · Score: 1

      I never meant to suggest that it is optimal. But it certainly is "optimized!" Vectorizing this function is simply ridiculous.

      That said, I just ran a benchmark, comparing it to the more straightforward code output by G++ 4.4. The vectorized version produced by 4.8 is slightly faster, by about 12%. The recursive approach is still quite a bit slower than a lookup table or switch-case. Interestingly, the lookup table and switch-case versions got slightly slower in 4.8 compared to 4.4.

    7. Re:Vectorized factorials! by Mr+Z · · Score: 1

      FWIW, I ran the same test on an older machine with G++ 3.4. (1.2GHz Duron, if you're curious.) G++ doesn't optimize the switch-case into a lookup table. On that system, the switch-case code ran 1/3rd the speed of an explicit lookup table. The switch-case turns into a jump table, so you end up with an indirect branch, move, and unconditional branch on any given path through the switch-case. The unconditional branch is easy for hardware to handle. The indirect branch, not so much, especially since I sent a pseudorandom sequence of inputs to the function.

      So, this goes back to what someone said in a comment elsewhere on this article: Trust, but verify. Trust your compiler to do a good job, but verify that it actually is.

    8. Re:Vectorized factorials! by loufoque · · Score: 1

      A manual optimization would easily yield a 2 times improvement on that.

    9. Re:Vectorized factorials! by Mr+Z · · Score: 1

      You mean on the recursive version? You get an order of magnitude speed up just switching to a trivial lookup table...

    10. Re:Vectorized factorials! by loufoque · · Score: 1

      But that's a change of algorithm, not something a compiler can do.

    11. Re:Vectorized factorials! by DickBreath · · Score: 1

      That is interesting. Since the entire purpose of a switch() construct in the programming language is to introduce a "computed goto" or lookup table into the object code, a compiler that does not generate this type of code should be called a pessimizing compiler. The opposite of an optimizing compiler.

      Optimizing compiler: generates code better than the obvious translation.

      Pessimizing compiler: generates code worse than the obvious (and even intended!) translation.

      Languages going all the way back to FORTRAN had various forms of 'computed goto' that were intended to be more efficient than a 'stacked if-then-elseif-elseif' construction. If a switch() generates a stacked if-then-elseif construction, then the switch statement has no place in the programming language, as there already are statements that generate precisely this construction.

      --

      I'll see your senator, and I'll raise you two judges.
    12. Re:Vectorized factorials! by Mr+Z · · Score: 1

      I think you misunderstood here: There were two different levels of optimization that happened depending on the compiler I used. Both were much faster than a stacked ifelse construction.

      On the older GCCs and other tool-chains, I got code roughly equivalent to FORTRAN's computed GOTO. The switchcase became roughly goto label_table[ switchvar ], and each of the cases had a branch back to the common join point. That's not pessimizing at all. For the general switchcase statements with relatively dense case values, that's pretty much what you need to do.

      On newer GCCs, for this particular construct, where every case was of the form x = value , it got rid of all the branches and replaced it with a lookup table on x itself, removing nearly all the branches (except some basic range guards), and generating, roughly, x = lookup_table[ switchvar ], which is quite a fundamental leap over normal switchcase reduction.

      So to re-cap, the default behavior is to generate a lookup table of branch targets. That's what I expect is a baseline minimum for switchcase code generation, and I think we agree on that. On modern deep-pipeline processors, branches with variable targets tend to be very expensive (the BTB needs to guess correctly, and often it can't if the inputs vary wildly), but they still may be the best choice for some algorithms. The more advanced optimization that I was surprised to see GCC implement replaced the computed-GOTO construct with an actual lookup table on the value itself. This eliminates the computed branch entirely and is a huge win (order of magnitude!) on modern architectures, when it can be applied.

  8. Why is this still a topic? by excelsior_gr · · Score: 3, Interesting

    This is 2013 (almost 2014!) why are we talking about vectorization? Why don't people write code in vector notation in the first place anyway? If Matlab and Fortran could implement this 25 years ago, I am sure we are ready to move on now...

    1. Re:Why is this still a topic? by mjwalshe · · Score: 1

      Its not C++ and OO and for some reason C++ devs seem not to want to learn fortran for technical programming which is still fortrans main use

    2. Re:Why is this still a topic? by Anonymous Coward · · Score: 0

      Modern Fortran can handle OO

    3. Re:Why is this still a topic? by Anonymous Coward · · Score: 0

      Pfft!

      Matlab just recently (2010?) started making use of SSE. Or, at least just started requiring computers WITH SSE2 to run.

    4. Re:Why is this still a topic? by Anonymous Coward · · Score: 0

      That's because Any language you dislike is a piece of shit. Never under any circumstance should anyone ever use it.

      FTFY. What a fucking ignorant you are.

    5. Re:Why is this still a topic? by Anonymous Coward · · Score: 0

      Here is a single line of fortran.

      value = function_or_array(1)

      You tell me which one it is. Am I passing the value 1 to a function or am I accessing the first element of an array?

      In real languages this has no ambiguity.

      value = function(1);
      value = array[1];

    6. Re:Why is this still a topic? by ebno-10db · · Score: 1

      That's the biggest complaint you have about Fortran, some minor syntactic detail? If that's it's biggest problem, then Fortran must be the greatest language ever created.

    7. Re:Why is this still a topic? by Anonymous Coward · · Score: 0

      Many of us attempt not to, but it's not so simple. BOOST's ublas is a bit underwealming, and research projects like SALT are much more interesting, but don't have a ton of maturity.

    8. Re:Why is this still a topic? by loufoque · · Score: 1

      Because the slowest part of the computer is memory, and vector notation leads to more cache misses.

    9. Re:Why is this still a topic? by Anonymous Coward · · Score: 0

      This is not a problem, because there is no ambguity. You are assigning a value/object/whatever, where that value comes from does not matter. If it does, you are Doing It Wrong.

      Note that the compiler will (usually) check types, so there is no risk of assigning the wrong type / experiencing the joy of (insert "modern" language here) where anything might be everything or the other way around. With proper coding, it will also check the argument/subscript for the array/function for e.g. boundary violations...

      Disclaimer: I'm an old (29) Fortran coder fresh out of academia and frustrated by the general sloppiness of enterprise-class Shell scripts and COBOL ;-)

    10. Re:Why is this still a topic? by excelsior_gr · · Score: 1

      And this is exactly how Fortran programmers like it. It keeps incompetent people from messing with our code.

    11. Re:Why is this still a topic? by david_thornley · · Score: 1

      Okay, so what difference is there really? An array is, essentially, a function from a sequence of integers. It looks a bit odd (although no worse than Common Lisp's "(aref foo 1)"), but what's the harm in that?

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    12. Re:Why is this still a topic? by hicksw · · Score: 1

      APL WTF!

  9. That might well be a bug by Anonymous Coward · · Score: 1

    I just had one of those "WTF was I thinking then". An old C program of mine started dumping code. Long story short: I did one of those things in the "don't do that" category: a function scans a text buffer, stuffs a null byte here and there and returns pointers into the buffer: think tokenizing.

    Point is... the buffer was stack allocated in this function! Don't try this at home, I say :-)

    A newer gcc saw the buffer wasn't being accessed within the function and thought "meh, after return this buffer is toast anyway. No need to write those pesky NULLs. No one will see that!".

    The compile with the old compiler "just worked" because nobody touched the stack in the meantime: the caller copied away the bits needed. Sheer luck, I'd say.

    So it may well be that there are some undefined behaviours in there which fall prey to a more aggressive optimizer. Try compiling with -O0 and see whether there's any difference in behaviour. If there is... happy bug hunting :-)

  10. Trust but verify by QuietLagoon · · Score: 2

    ...do you trust that the compiler is generating the best code for you?,,,

    Trust, but verify.

    .
    I come from the days when it was the programmer, not the compiler, that optimized the code. So nowadays, I let the compiler do its thing, but I do a lot of double-checking of the generated code.

    1. Re:Trust but verify by Mr+Z · · Score: 1

      I'm in the same camp.

      It's also worth noting that C and C++ make it really easy to trip up the optimizer and disqualify code from certain optimizations. Little things like const, restrict, alignment and trip-count hints can go a long way, though. Reviewing the generated code can highlight places where these hints would be useful.

  11. Machine code you fucking witless poser! by Anonymous Coward · · Score: 0

    To be kind.

    1. Re:Machine code you fucking witless poser! by Anonymous Coward · · Score: 0

      No, the compiler spits out assembly. The assembler is what turns that into machine code.

    2. Re:Machine code you fucking witless poser! by Anonymous Coward · · Score: 1

      Educate yourself. Is it not embarrassing to fling all this poo only to find out you are wrong?

    3. Re:Machine code you fucking witless poser! by VortexCortex · · Score: 2, Informative

      I write code in Machine Code with a bootable hex editor (446 bytes, fits in a HDD boot sector). It's the easiest way to bootstrap an OS from scratch now that MoBos don't have boot from serial port anymore...
      Here, run it in a VM: "qemu-system-i386 hexboot.img ", if you want.
      Or, "dd if=hexboot.img of=/dev/sda bs=1 count=446 conv=notrunc", if you want to preserve the partition table on a bootable drive.
      Arrows,PgUp,PgDn,Home,End = navigate; Tab = ASCII/Hex, Esc = jump to segment under cursor, F8 = Run code at the cursor. (this is a real-mode version)
      When it boots you'll be looking at the code that booted, there's only two variables that didn't fit into the registers, you can see them changing at the bottom of the code as you stroll around.

      That's all you need to create an OS, complier, etc. from scratch. You'll probably destroy your system though if you're not careful, so keep in in the VM if you're a noob; Lock-up is a mild danger, but corrupting the CMOS, etc. can leave your system bricked. You can replace the BIOS too if you know what you're doing. Maybe some day I'll publish a path to go from zero to OS while avoiding the Ken Thompson Compiler Hack... Folks are only just beginning to get interested in having actual system security, so maybe we'll lick the problem some other way. There's still chip microcode to worry about, but programmable hardware may allow us to route that exploit vector out too some day.

      Screw your bullshit optimized compiler crap. It's stupid and far slower than you think, esp. since the binaries are bigger (1 cache miss and I've already beaten you in most cases). Besides, Next year or so the system will run twice as fast. My need for speed is tempered by my greater need for security and readable machine code. If I identify a patch of code that needs to be optimized or vectorized, I can do it myself.

      Premature optimization is the root of all evil.
      - Donald Knuth

      I don't care about my lawn, it's just there to keep the dirt intact.

    4. Re:Machine code you fucking witless poser! by bws111 · · Score: 2

      Hey genius, try removing the 'as' command and then run gcc. Let us know how well the compiler works without an assembler.

    5. Re:Machine code you fucking witless poser! by Anonymous Coward · · Score: 0

      There is no way to optimize post-compile. Compiling to asm form made sense when machines came in MB sizes but back then this asm was used as a starting point and then taken up by hand to be refined by an expert (in those days, if you coded you were an expert, by def.). A compiler going to an assembler today is LAME.

    6. Re:Machine code you fucking witless poser! by loufoque · · Score: 1

      Actually, no. Computers are not getting faster.
      Microprocessors stopped getting faster a few years ago, now we just get more of them. Supercomputers have mostly reached the limits of scalability, so there is a limit to that too.

  12. Nope by Anonymous Coward · · Score: 0

    While I really want to believe that AMD is taking a huge leap with the ubiquitous console chipping, it's still a little too early to declare it a success.

  13. Re:yuo Fai7 It by LordByronStyrofoam · · Score: 3, Funny

    OMG! What's this goatse doing here?? I thought all these images were taken down by a DMCA notice by the original asshole!

    --
    Slashdot's name? When my compiler sees /. it generates a warning about a badly formed comment.
  14. Mantle? by Anonymous Coward · · Score: 2, Insightful

    Mantle is a good idea insofar as it should kick Microsoft and/or NVIDIA up the behind. We desperately need someone to cure us of the pain that is OpenGL and the lack of cross platform compatibility that is Direct 3D.

    Obviously NVIDIA won't play ball with Mantle but I've got a feeling they might have to eventually given that some AAA games developers are going code a path for it. When it starts showing up how piss-poor our current high level layers are compared to what the metal can do, they'll have no choice.

  15. Clang/LLVM. by Anonymous Coward · · Score: 1

    'Nuff said.

  16. Re:Perhaps by Anonymous Coward · · Score: 0

    I've had code generator bugs in a c++ compiler from SGI in 1995. I was trying to do what is now called RAII. The compiler didn't really like objects on the stack, in fact it called the destructor twice, even after the stack frame was reused by another function call. I gave up on c++ for the next 30 years.

  17. When the manual is tl;dr by tepples · · Score: 2

    When documentation runs to hundreds or thousands of pages, it's hard to read it from cover to cover and reread it when each new version comes out.

    1. Re:When the manual is tl;dr by jthill · · Score: 1

      That's why professionally-produced documentation comes with change bars or better for printed docs and embedded revision history for binaries.

      --
      As always, all IMO. Insert "I think" everywhere grammatically possible.
  18. AMD has no 100% monopoly by tepples · · Score: 1

    the day that AMD came out with Mantle and started leveraging it's 100% monopoly in the console market

    Among consoles that aren't discontinued or battery-powered, I count Xbox 360, PlayStation 3, Wii U, Xbox One, PlayStation 4, and OUYA. Of these, two have NVIDIA graphics: PlayStation 3 has RSX, and OUYA has the same Tegra 3 that's in the first-generation Nexus 7 tablet. The forthcoming iBuyPower Steam Machine also has NVIDIA graphics.

  19. Re:Perhaps by mevets · · Score: 1

    Was your program dealing with dates or tenses?

  20. Creating your own ABI by tepples · · Score: 1

    sometimes I want to reserve a global variable in a fixed register, but that requires all modules be compiled with the same flag.

    That isn't "breaking the rules" as much as creating your own ABI. Classic Mac OS on 68K used to do this, where register A5 was typically reserved as a pointer to the program's global variable segment because the Mac OS ABI used position-independent code.

  21. Object code formats by tepples · · Score: 1

    A compiler going to an assembler today is LAME.

    How so? A tool should do one thing well. What an assembler does well is generate relocatable object code in a given format. If you're targeting two platforms, one of which uses ELF and the other COFF or whatever, one could use the same compiler to target both along with two different assemblers, one for each object code format.

    1. Re:Object code formats by Anonymous Coward · · Score: 0

      One tool, one job is a good rule of thumb. But tell me how to handle link-time, inter-procedural optimization. Now we have two jobs--linking and optimization--which can't be separated out. We're forced to put them into the same utility.

      We can still apply the one tool, one job rule, but the frame of context is our application design, not inter-process separation of concerns.

  22. re by Anonymous Coward · · Score: 0

    That is a photo of a torn up pumpkin...

  23. try a more complicated version by Chirs · · Score: 1

    if (a && b=f(a) && c=g(b)) {
        do stuff with a and b and c
    }

    If you convert that into the other format then you need to add something like six lines of code and two levels of nested if statements.

    1. Re:try a more complicated version by EvanED · · Score: 1

      I tried that example. It has a syntax error.

      If I fix the syntax error -- by parenthesizing b=f(a) and c=g(b) -- then there's no warning with GCC 4.5, -O2 -Wall -Wextra.

  24. Re:Perhaps by Anonymous Coward · · Score: 0

    Ah, so you've just got 11.5 or so years until you can get back to C++. Cool. We'll keep it warm for you!

  25. Re: Perhaps by O('_')O_Bush · · Score: 1

    Well, what are they using in 2025?

    --
    while(1) attack(People.Sandy);
  26. Excuse me? Intel never said it would support AMD. by Anonymous Coward · · Score: 0

    We do not live in a society that one must support the competitor. If the processor was not Intel produced several functions were disabled. A perfectly acceptable solution as there was no QA done for non-Intel products. It was also done in the open, if you RTFM you would have discovered that the compiler ONLY supported Intel processors.

  27. Harumpf by sgt+scrub · · Score: 1

    As soon as I get my C++ loops to end I'll worry about converting them to ASM.

    --
    Having to work for a living is the root of all evil.
  28. Probably optimizing for larger numbers by Chirs · · Score: 1

    I suspect the vectorized version of fact(1000000) is faster than the naive implementation.

    1. Re:Probably optimizing for larger numbers by Mr+Z · · Score: 1

      Well, I just compared the vectorized implementation to the simple tail-call optimized version (ie. reduced to a simple loop) that GCC 4.4 produced.

      The vectorized version was a paltry 6% faster on my box, measured across 65,536 iterations. (My machine is a AMD Phenom X4, 3.4GHz.)

      So, it is faster, but not by a meaningful amount, and probably not enough faster to justify the hilarious code size increase.

  29. Comparing G++ and Intel Compilers and Vectorized C by Anonymous Coward · · Score: 0

    Intel's foundations will shake when they see what is in store for them soon
    Kaveri is really a 12 core monster faulty codes won't save them when the 12 core monster is unleashed

  30. Maybe a waste of intellect though? by Anonymous Coward · · Score: 0

    Think of the waste of intellect that this situation creates, I mean the people with the smarts to do what you are describing would probably enjoy the process(of reverse engineering), but they could just as well be making things with the functionality instead of having to reverse engineer the hidden functionality and then presumably making things...
    But then again, I realize that reverse engineering it would probably engender a deeper knowledge of the functionality than just perusing the documentation.

  31. Re:Excuse me? Intel never said it would support AM by MakerDusk · · Score: 1

    It sabatoges for non-intel. We're talking about a compiler. It shouldn't matter what brand of CPU is being used.