4 ms·
> The article's charts show that in this case, naive code gets you less than 2% the performance of an optimised implementation. That's not what the chart show
by qayxc 5y ago
> The article's charts show that in this case, naive code gets you less than 2% the performance of an optimised implementation.
That's not what the chart shows at all. The charts shows what non optimized code compiles to.
Just run the code through any optimizing compiler released in the past decade and you'll find that do the vectorization for you. No need to use non-portable intrinsics.
Even the block optimisation can be done in plain C.
While optimised algorithms are better than naive algorithms, optimising machine code is indeed a compiler task. Some languages tend to do a better job of describing the algorithm than others, but that's a different can worms entirely.
- gpderetta 5y agoI think that by non-optimized the chart refers to not hand-optimized. The code is likely still compiled via -O3. In theory the GCC is capable to do all these optimizations, even loop tiling, vectorization and autopar as it indeed has a polyhedral representation of loops. In practice it might be another story of course.
- qayxc 5y ago> The code is likely still compiled via -O3. That doesn't matter. You have to specify the target platform as well. Just take the naive code and specify -O3 in godbolt.org for example. Assembly exerpt of the inner loop: L5: movss xmm0, DWORD PTR [rax] mulss xmm0, DWORD PTR [rdx] add rax, 4 add rdx, rdi addss xmm1, xmm0 movss DWORD PTR [rcx], xmm1 cmp rsi, rax jne .L5 No AVX in sight. Now specify -mavx2 -mfma and compare the inner loop: .L5: vmovss xmm2, DWORD PTR [rax] vfmadd231ss xmm0, xmm2, DWORD PTR [rdx] add rax, 4 add rdx, rdi vmovss DWORD PTR [rcx], xmm0 cmp rsi, rax jne .L5 Case in point: without providing the compiler flags used for compilation, charts are misleading at best and outright wrong at worst.
- gpderetta 5y agoI believe the flags are in the compile.sh script in the repo: OMP_NUM_THREADS=8 g++ -Wall -std=c++11 -fopenmp -D_USE_OPENBLAS -O3 -L/usr/lib -lopenblas -I /usr/include/openblas -march=native -mavx2 -mfma -funroll-loops compare_blas.cpp -lopenblas -o matmul Of course it is possible that different flags were used to benchmark the naive version. edit: and of course those f*ss suffixes show that the compiler is not actually vectorizing the loops, just using the avx encoding of scalar instructions (plus fma). edit2: likely -ffast-math is also required for vectorization as it will change the sequence of operations, but after experimenting with it a bit it seems that in this case is still not sufficient.