4 ms·
I would be surprised if optimization was the actual goal. C++ is not faster than C.
by mratsim 7y ago
I would be surprised if optimization was the actual goal. C++ is not faster than C.
- Ididntdothis 7y agoIt’s not faster but it’s also not much slower. I think some features of C++ Would be hard to optimize by a compiler that doesn’t understand them so a C++ to C compiler may produce slow or bloated code.
- mratsim 7y agoIn embedded development C++ is often frowned upon because in the past people used C++ features that bloated the code. Regarding features that may not be properly optimized, there are exceptions and move semantics I guess, but exceptions are often avoided like the plague anyway and code can be refactored to get the same effect as move semantics. Am I missing something?
- pjmlp 7y agoNot only does C++ provide features that straight C optimizers won't be able to match like templates and constexpr, C++ shares a common subset with C, and libc all major C compilers is actually written in C++ with extern "C" entry points nowadays. This "C is faster than C++" is a bit dated by now.
- mratsim 7y agoI didn't say C is faster than C++, I said C++ is not faster than C and so speed is probably not the main driver behind implementing a C++-->Assembly pipeline without intermediate C.
- pjmlp 7y agoPlaying word games here? "I said C++ is not faster than C" implies that C++ compilers don't beat C compilers, which as many in HPC, HFT and GPGPU computing domains know is false for years now, and no restrict doesn't help that much against template metaprogramming and constexpr.
- mratsim 7y agoI'm not playing word games. Template metaprogramming and constexpr doesn't help being faster in HPC or GPGPU, it helps reduce the redundancy of your code, for example if you want a generic algorithm on float, double, int, complex. What helps speed is being able to control memory allocations and having the tool to place the data required on registers, L1 cache or L2 cache as required by your kernel (and similarly for GPU). On current architectures, what is hard to optimize is memory and data movement, if your data is at the wrong place or not prefetched at the right time it will be literally 100 times more costly than a saved addition from constexpr.
- pjmlp 7y agoEnough theory, "Scientific Computing: C++ Versus Fortran" (1997) https://www.drdobbs.com/cpp/scientific-computing-c-versus-fortran/184410315 https://www.drdobbs.com/cpp/scientific-computing-c-versus-fo... "Micro-Optimisation in C++: HFT and Beyond" http://research.ma.cx/NDCTechTown_2017_JMMcG_v1_1.pdf http://research.ma.cx/NDCTechTown_2017_JMMcG_v1_1.pdf "The Speed Game: Automated Trading Systems in C++" https://www.youtube.com/watch?v=ulOLGX3HNCI https://www.youtube.com/watch?v=ulOLGX3HNCI "When a Microsecond Is an Eternity: High Performance Trading Systems in C++" https://www.youtube.com/watch?v=NH1Tta7purM https://www.youtube.com/watch?v=NH1Tta7purM
- mratsim 7y agoIt might be Internet and the issue of communicating emotions across but you sound quite taken by this issue. Anyway, I stand by what I say and I'm backed by my high performance code: - Writing matrix multiplication that is as fast as Assembly, complete with analysis and control on register allocations, L1 and L2 cache tiling and avoiding TLB cache miss: - https://github.com/numforge/laser/blob/master/laser/primitives/matrix_multiplication/gemm_tiling.nim#L284-L305 https://github.com/numforge/laser/blob/master/laser/primitiv... - Code, including caveat about hyperthreading: https://github.com/numforge/laser/blob/master/laser/primitives/matrix_multiplication/gemm.nim#L116-L138 https://github.com/numforge/laser/blob/master/laser/primitiv... - The code is all pure Nim and is as fast/faster than OpenBLAS when multithreaded, caveat, the single-threaded kernel are slightly slower but it scales better on multiple cores. - I've also written my own multithreading runtime. It's scale better and has lower overhead than Intel TBB. There is no constexpr, you need type-erasure to handle everything people can use a multithreading runtime for, same comparison on GEMM: https://github.com/mratsim/weave/tree/v0.4.0/benchmarks/matmul_gemm_blas https://github.com/mratsim/weave/tree/v0.4.0/benchmarks/matm... - More resources on the importance of memory bandwidth: optimization convolutions https://github.com/numforge/laser/wiki/Convolution-optimisation-resources https://github.com/numforge/laser/wiki/Convolution-optimisat... - Optimizing matrix multiplication on GPUs: https://github.com/NervanaSystems/maxas/wiki/SGEMM https://github.com/NervanaSystems/maxas/wiki/SGEMM, again it's all about memory and caches optimization - Let's switch to another domain with critical perf need, cryptography. Even when knowing the bounds of iterating on a bigint at compile-time, compiler are very bad at producing optimized code, see GCC vs Clang https://gcc.godbolt.org/z/2h768y https://gcc.godbolt.org/z/2h768y - And crypto is the one thing where integer templates are very useful since you know the bounds. - Another domain? VM interpretation. The slowness there is due to function call overhead and/or switch dispatching and not properly using hardware prefetchers. Same thing, C++ constexpr doesn't help it's lower-level, see resources: https://github.com/status-im/nimbus/wiki/Interpreter-optimization-resources https://github.com/status-im/nimbus/wiki/Interpreter-optimiz... Also all the polyhedral research, and deep learning compiler research including the Halide compiler, Taichi, Tiramisu, Legion, DaCE confirm that memory is the big bottleneck. Now since you want to stop on the theory and you mentioned HPC, pick your algorithm, it could be matrix multiplication, QR decomposition, Cholesky, ... Any fast C++ code (or C, or Fortran or Assembly) that you find will be fast because of careful memory layout and all level of caches, not constexpr. If you have your own library in one of those domains I would be also very happy to have a look. As a simple example, let's pick an out-of-place transposition kernel to transpose a matrix. Show me how you use constexpr and template metaprogramming to speed it up. Here is a detailed analysis on the impact of 1D-tiling and 2D tiling: https://github.com/numforge/laser/blob/master/benchmarks/transpose/transpose_bench.nim https://github.com/numforge/laser/blob/master/benchmarks/tra..., throughput can be increased 4x with proper usage of memory caches.