Besides the autovectorization, the second version also has two additional assignments. Depending on how the storage is used for these, whether it’s to registers, L1/L2, or stack, there might be performance hit.
Why does this code execute more slowly after strength-reducing multiplications?
91–100 of 155 posts
Re: Why does this code execute more slowly after strength-reducing multiplications?
#92The part about data dependencies across loop iterations is fascinating to me, becuase it's mostly invisible even when you look at the generated assembly. There's a related optimization that comes up in implementations of ChaCha/BLAKE, where we permute columns around in a kind of weird order, because it breaks a data dependency for an operation that's about to happen: https://github.com/sneves/blake2-avx2/pull/4#issue…
Re: Why does this code execute more slowly after strength-reducing multiplications?
#93Oh 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?
#94Earlier quoted context omitted.
That is correct. But we were talking about how the == operator compares zeros. According to IEEE 754, -0 == +0 even though their bit patterns are not identical. And, by the way, inf != inf even if their bit patterns are identical.
You mean nan right?
Re: Why does this code execute more slowly after strength-reducing multiplications?
#95Seems like you can have the cake and eat it too, by manually parallelizing the code to something like this: double A4 = A+A+A+A; double Z = 3A+B; double Y1 = C; double Y2 = A+B+C; int i; // ... setup unroll when LEN is odd... for(i=0; i Probably not entirely functional as written, but you get the idea: unroll the loop so that the data dependent paths can each be done in parallel. For the machine being considered, a 4…
Looks like someone wrote pretty good parallelizable code on the original question, here: https://stackoverflow.com/a/72333152
Re: Why does this code execute more slowly after strength-reducing multiplications?
#96Seems like you can have the cake and eat it too, by manually parallelizing the code to something like this: double A4 = A+A+A+A; double Z = 3A+B; double Y1 = C; double Y2 = A+B+C; int i; // ... setup unroll when LEN is odd... for(i=0; i Probably not entirely functional as written, but you get the idea: unroll the loop so that the data dependent paths can each be done in parallel. For the machine being considered, a 4…
Re: Why does this code execute more slowly after strength-reducing multiplications?
#97Vectorisation is not free, There is one other dimension to optimise for: power. The suggested "slower" optimisation does fundamentally use less instructions. Chucking more hardware at parallelisable problems makes it run faster but does not necessarily reduce the power requirements much because there are fundamentally the same number of instructions, it's just gobbling up the same power over a shorter period of time…
Re: Why does this code execute more slowly after strength-reducing multiplications?
#98Earlier 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.
That doesn’t matter for the case where a compiler would like to replace x + y by x because it knows y == 0 . The compiler would have to test for the x == -0 case, and doing that ¿rarely/never? is faster than computing x + y .
Re: Why does this code execute more slowly after strength-reducing multiplications?
#99Earlier quoted context omitted.
More generally, “stop storing state, unless it makes the program less complicated.” The first version is simple. The second version is more complicated. The simplicity is because the first version can be represented as a formula; imagine trying to write out the second version as a formula, and the complexity becomes obvious. (The addition loop would have to be written as a recurrence relation, which of course means e…
> stop storing state, unless it makes the program less complicated I had hoped that functional programming languages would lead us to automatic high-level parallelization. That hasn't happened much in the real world. But what we got is "write code like a functional programmer would even in a low-level language and the compiler and the ISA will parallelize it for you." That surprises me, but I'll take it.
The relative novelty and paucity of functional languages in the ecosystem means the incentive story hasn't happened to get the end-to-end from compiler through to execution so tight yet. I expect it'll happen, and when it does I expect the result will trigger fewer questions like this one because a newer generation of programmers well be less inclined to assume serial execution.
Re: Why does this code execute more slowly after strength-reducing multiplications?
#100Earlier quoted context omitted.
Would it not be in Intel's best interest to have popular compilers be able to squeeze the most performance out of its own line of CPUs? I'm wondering how the incentives play out to keep this stuff private?
Intel sells a compiler. I've only used it briefly a long time ago, but its code generation was well ahead of MSVC at the time even for scalar (non-SIMD) stuff, and I remember GCC was far behind too (it would generate roughly the same performance in microbenchmarks, but far more bloated.)
https://www.intel.com/content/www/us/en/developer/articles/n...
I think software is not a huge profit center for them.
The original comment presents:
> The actual details there are [1] too secret for Intel to want to accurately describe them in gcc, [2] they’re different across different CPUs, [3] and compilers just aren’t as good as you think they are.
2 and 3 could just be the whole story. Although we haven't actually accumulated any evidence here for 3, given that the original story was about surprisingly getting beat by a compiler, despite performing a seemingly obvious optimization.