Earlier quoted context omitted.
> The second code can probably become SIMD as well, but it's beyond GCC's ability to autovectorizer it in that form. Usually, for floating point operations the compiler simply has no chance to do anything clever. NaNs, infinities and signed zero mean that even the most "obvious" identities don't actually hold. For example, x + 0 == x (where the == is bitwise) does not hold for x = -0.
> For example, x + 0 == x (where the == is bitwise) does not hold for x = -0. But when operating on floating point numbers, == is not bitwise, and -0 == +0.
Why does this code execute more slowly after strength-reducing multiplications?
61–70 of 155 posts
Re: Why does this code execute more slowly after strength-reducing multiplications?
#62Re: Why does this code execute more slowly after strength-reducing multiplications?
#63Re: Why does this code execute more slowly after strength-reducing multiplications?
#64Re: Why does this code execute more slowly after strength-reducing multiplications?
#65Is anyone aware of good tooling for automatically catching this sort of thing even some of the time?
Re: Why does this code execute more slowly after strength-reducing multiplications?
#66Earlier quoted context omitted.
That is the 'why' autovectorization fails. But it seems solvable in this case pretty easily actually. EDIT: Solvable by a human. I dunno much about compilers though, so I dunno if there's some kind of language issue that would prevent the unrolling of this dependency.
I think the point GP is making is that even without vectorization, the data dependency causes stalls even in normal, single data instructions. That is, a data dependency between iterations of loops will hurt performance even for non-vectorizable calculations (or on CPUs with high ILP but no really good vector instructions, which granted is probably a small pool since both those things came about at about the same tim…
Loop-carried dependency is the big culprit here. I wish we had a culture of writing for loops with the index a constant inside the loop, as in the Ada for statement, and not the clever C while loops or for with two running variables... Simpler loop syntax makes so many static analyses 'easier' and kind of forces the brain to think in bounded independant steps, or to reach for higher level constructs (e.g. reduce).
Re: Why does this code execute more slowly after strength-reducing multiplications?
#67Oh man I have been smoked by data-dependency like this so many times. I've gotten a lot better over the years at "seeing" data dependencies in godbolt or whatever, but it still slips through by my code and that of my colleagues way more often than I'd like. Is anyone aware of good tooling for automatically catching this sort of thing even some of the time?
Re: Why does this code execute more slowly after strength-reducing multiplications?
#68In the post, multiplications and 2 additions are not faster than 2 additions. The post compares (1) loop code that can be vectorized, as loop rounds are independent and do not depend on the result from the previous round, and (2) an "optimization" that makes calculations shorter, but also makes each loop round depend on the result of the previous round, so this cannot be vectorized.
Re: Why does this code execute more slowly after strength-reducing multiplications?
#69Earlier quoted context omitted.
> For example, x + 0 == x (where the == is bitwise) does not hold for x = -0. But when operating on floating point numbers, == is not bitwise, and -0 == +0.
If the user provides code where the result should be +0.0 and the compiler emits code that results in -0.0 (and the user has not explicitly enabled relaxed IEEE754 conformance), that's a bug in the compiler.
Re: Why does this code execute more slowly after strength-reducing multiplications?
#70Funny that this question gained 180 upvotes in 10 days when it also could have received the reverse for being quite lacking in things the author has tried to figure the (rather obvious) data dependency out on his own.