Skip to content
Search

Less slow.cpp

lastmod 2025-04-21created 2025-04-213 edits

Learn to write less slow C/C++ code

Playing around "Less Slow" coding practices in C++ 20, C, CUDA, PTX, & Assembly, from numerics & SIMD to coroutines, ranges, exception handling, networking and user-space IO

About

  • Open-source project for learning high-performance C/C++ and assembly coding techniques through practical examples
  • Includes examples of using optimized libraries instead of the STL and various hardware optimization techniques
  • Explains various performance tricks, such as input generation cost, approximating math functions, CPU branch prediction, and multi-core parallelization
  • Broadly covers platform-specific optimization techniques for CUDA, PTX, ASM, FPGA, JSON processing, etc., as well as how to measure benchmarks
  • Provides automation for running benchmarks and processing statistics, based on Google Benchmark

Writing performance-oriented C/C++ and assembly code

  • This project is a collection of benchmark code that helps build the intuition and mindset needed to design high-performance software
  • Covers practical coding examples for avoiding common bugs, security issues, performance bottlenecks, etc. in modern code
  • Systematically introduces practical performance-oriented techniques that are hard to come across in university courses or bootcamps
  • Most code runs on Linux with GCC and Clang, but Windows and macOS are partially supported
  • Also introduces parallel algorithms, coroutines, polymorphism, etc. for implementing high-performance code

Key topics

  • Random inputs 100x cheaper?! Input generation can be slower than the algorithm itself
  • 1/40 the cost at 1% error: approximating STL trigonometric functions like std::sin in just 3 lines of code
  • Lazy logic 4x faster? Implementing extreme laziness with custom std::ranges and iterators
  • Compiler optimizations beyond -O3: hidden flags and tricks can double performance again
  • Matrix multiplication is the problem? A 3x3x3 GEMM can be 70% slower than 4x4x4 despite 60% fewer operations
  • The truth about AI scaling? Measuring the gap between theoretical ALU throughput and actual BLAS performance
  • How many conditionals is too many? Testing the limits of the CPU branch predictor in just 10 lines of code
  • Is recursion better? Measure the stack depth yourself to see where the SEGFAULT happens
  • Why avoid exceptions? Want to try alternatives like std::error_code or std::variant?
  • Scaling to multiple cores? How to use OpenMP, Intel oneTBB, or your own thread pool
  • How to process JSON without memory allocation? Is C++20 better, or are old-school C99 tools simpler?
  • How to use custom keys and transparent comparators to use STL associative containers properly?
  • Is there a way faster than a hand-written parser? Going head-to-head with a consteval-based regular expression engine
  • Are pointers really 64 bits? Let's use pointer tagging
  • How many packets does UDP drop? Let's go as far as handling web requests in user space with io_uring
  • Implementing 50% faster vectorized non-contiguous memory operations with Scatter-Gather
  • Intel oneAPI vs Nvidia CCCL? What's special about <thrust> and <cub>?
  • How do CUDA C++, PTX, and SASS differ from CPU code?
  • Performance-sensitive code? Comparing which to choose: intrinsics, inline asm, or .S files
  • Tensor Cores and memory architecture — how do the CPU and Volta, Ampere, Hopper, and Blackwell GPUs differ?
  • How does FPGA coding differ from GPUs? What's the difference between high-level synthesis (HLS), Verilog, and VHDL? 🔜 #36
  • What is an Encrypted Enclave? Comparing the latency of Intel SGX, AMD SEV, and ARM Realm 🔜 #31

External libraries used

  • Google Benchmark: performance measurement
  • Intel oneTBB: parallel STL backend
  • Meta libunifex: asynchronous execution model
  • range-v3: replacement for std::ranges
  • fmt: replacement for std::format
  • StringZilla: replacement for std::string
  • CTRE: replacement for std::regex
  • nlohmann/json, yyjson: JSON parsers
  • Abseil: high-performance containers
  • cppcoro: coroutine implementation
  • liburing: Linux kernel-bypass I/O
  • ASIO: asynchronous networking
  • Nvidia CCCL, CUTLASS: GPU algorithms and matrix operations

Google Benchmark usage tips summary

  • Register benchmarks with BENCHMARK(), pass parameters with ->Args({x,y})
  • Control compiler optimizations with DoNotOptimize() and ClobberMemory()
  • Control iteration count and benchmark time with ->Iterations(n) and ->MinTime(n)
  • Specify time complexity with ->Complexity(...) and ->SetComplexityN(n)
  • Control timing sections directly with state.PauseTiming() and ResumeTiming()
  • Custom counters can be registered with state.counters[...]

See also

Favorite site

author Zer0 sitemap