# Less Slow C++: a benchmark corpus you read as prose

> less_slow.cpp is one large C++ file plus CUDA, PTX and assembly siblings, organised into ordered `#pragma region` blocks that pair a measurement with an explanation in comments. It is a reading project with a build attached, and its own README says the numbers do not aim to cover every topic.

**ashvardanian/less_slow.cpp** — 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

- Repository: https://github.com/ashvardanian/less_slow.cpp
- Website: https://ashvardanian.com/tags/less-slow/
- Stars: 1,928 · Forks: 85
- Language: C++
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/ashvardanian-less-slow-cpp

## One file, ordered by difficulty, read top to bottom

The stated purpose is mindset rather than coverage. The README says the benchmarks do not aim to cover every topic entirely, but help form a mindset and intuition for performance-oriented software design. That framing explains the structure.

Everything lives in `less_slow.cpp`, a single translation unit organised into very long, ordered and nested `#pragma region` sections. The author is explicit that this is not necessarily the preferred form for everyone, which is unusual candour for a code repository. The upside is that reading is linear: you scroll, you hit a region, and the comments around the benchmark tell you what the measurement is supposed to show.

The advice for readers is direct. Jump to the source file, read the snippets and their comments, and use the navigation bar in your IDE to move between `#pragma region` blocks. The project is designed to be read, with the build as an optional second pass that lets you check whether the numbers on your hardware resemble the ones in the comments.

The topic list spans micro-kernels that execute in a few nanoseconds up to parallel algorithms, coroutines and polymorphism, across C++20, CUDA, PTX and assembly.

## Getting it to build with GCC on Linux

The README recommends GCC on Linux for the broadest functionality, with WSL suggested on Windows and a non-native Homebrew or MacPorts Clang on macOS. The full sequence it gives is worth keeping verbatim, since the third-party libraries are compiled from source rather than linked from the system.

```sh
git clone https://github.com/ashvardanian/less_slow.cpp.git
cd less_slow.cpp

pip install cmake --upgrade
sudo apt-get install -y build-essential g++
sudo apt-get install -y pkg-config liburing-dev
sudo apt-get install -y libopenblas-base

cmake -B build_release -D CMAKE_BUILD_TYPE=Release
cmake --build build_release --config Release
build_release/less_slow
```

Two details carry most of the setup cost. `pip install cmake --upgrade` is there because the PyPI distribution of CMake is newer than what some distributions package. And `liburing-dev` is a hard requirement for the io_uring section, which is the part of the corpus that does kernel-bypass networking from user space.

`libopenblas-base` matters for the numerics sections, where the project measures the gap between theoretical ALU throughput and what a BLAS implementation achieves. Without it those regions will not run.

On Linux you need CMake and a recent GCC or Clang with C++20 support. Compatibility is stated as GCC, Clang and MSVC across Linux, MacOS and Windows, but the code is designed primarily for GCC, Clang and NVCC on Linux.

## Dependencies compiled from source, not linked from the system

The build pulls and compiles several third-party libraries, which is the main reason a clean machine takes a while.

Google Benchmark does the profiling, so every measurement goes through the same harness and the same reporting. Intel's oneTBB acts as the Parallel STL backend. Meta's libunifex supplies senders and executors for the coroutine material. Eric Niebler's range-v3 replaces `std::ranges` where a more capable implementation is wanted, so the corpus can show what a different range library does rather than only what the standard one does.

This choice introduces a methodological bias. When a benchmark compares range-v3 against `std::ranges`, you are seeing range-v3 measured, and range-v3 is not the implementation in your production build.

The repository also brings in libraries that are not STL but are treated as de facto standards, imported through CMake and compiled from source. The README frames this as an explicit purpose of the project rather than a side effect.

The build system itself is CMake, with `CMakeLists.txt`, `CMakePresets.json`, a `.clang-format` and a `.cmake-format.py`. The second one is a small tell that the project tries to keep its own formatting consistent.

## The language siblings: CUDA, PTX and raw assembly

The repository is not a single C++ file with a CUDA afterthought. The top level carries `less_slow.cpp`, `less_slow.cu`, two assembly files, and three PTX files.

The corpus compares CUDA C++, PTX as an intermediate representation, and SASS, and asks how all of them differ from CPU code. It also covers Tensor Cores and memory behaviour across CPUs and across Volta, Ampere, Hopper and Blackwell generations.

There is a practical decision documented in the topic list: how to choose between intrinsics, inline `asm` and separate `.S` files for performance-critical code. Three options, three different maintenance costs, and the answer depends on which toolchain you are targeting.

The `.gitattributes` file in the repository root suggests the assembly and PTX files carry per-language handling, which is what you would expect from a repo mixing five languages in one directory.

## What the topics actually argue, grouped by kind

The README's highlight list is long, but the claims fall into recognisable groups and it is worth reading them as arguments rather than results.

The first group is about inputs and setup costs. One claim is that random input generation can be made 100x cheaper, on the premise that input generation sometimes costs more than the algorithm being measured. That is a benchmarking lesson as much as a performance one.

The second is approximation. Replacing STL math functions such as `std::sin` with a three-line approximation trades a stated 1 percent error for a 40th of the cost. Where such approximations are acceptable in your domain is the real question, and the repository does not claim they always are.

The third is compiler behaviour: flags and techniques beyond `-O3` that the README credits with another 2x, and the shape of numeric kernels, where a 3x3x3 GEMM is described as 70 percent slower than a 4x4x4 despite 60 percent fewer operations. Fewer operations being slower is the most transferable idea in the list, because it is about register blocking rather than arithmetic count.

The fourth group is about language constructs: 4x faster lazy logic using custom `std::ranges` and iterators, `std::error_code` and `std::variant`-like ADTs against exceptions, OpenMP and oneTBB and custom thread pools for many cores, allocation-free JSON handling, associative containers with transparent comparators, and `consteval` RegEx engines beating a hand-written parser.

The fifth is systems-level: how many UDP packets get dropped, serving web requests from user space with io_uring, scatter and gather for 50 percent faster disjoint memory operations, pointer tagging, and recursion depth before a SEGFAULT.

It also points at two topics marked as upcoming, FPGAs and High-Level Synthesis with Verilog and VHDL, and Encrypted Enclaves with latency figures for Intel SGX, AMD SEV and ARM Realm.

## Why these numbers should not be quoted as your numbers

There is a real limitation that the author states and then moves past, and readers should not move past it.

The benchmarks are measurements from one machine, on one compiler, with one set of third-party library versions. The README's own advice is to run the code in your environment and compare it to the comments as you read, which is an instruction to reproduce, not to cite. The headline figures depend on instruction set availability, CPU generation, BLAS implementation and build flags, and the repository covers several architectures precisely because the answer changes between them.

It is also a corpus with gaps. The author says the benchmarks do not cover every topic, and two headline items are marked as future work rather than written. Anything you take from here is intuition, not a specification.

There is another scope limit: this is a C++ and systems project. The author points readers who want higher-level abstractions and languages to `less_slow.rs` and `less_slow.py`, sibling repositories with a similar shape. If your work is in Python or Rust, this corpus is a source of ideas rather than something you can apply directly.

Two upcoming topics also signal where it does not go yet: FPGA coding versus GPU work, and encrypted enclave latency.

## Licensing, citation, and how the project is versioned

The repository is licensed under Apache-2.0, with the LICENSE file at the root. The permissive grant matters when copying code snippets into another codebase, provided its conditions are followed.

There is a `CITATION.cff` file at the top level, which is how the project asks to be cited if you use it in academic work. 

The versioning tells you what kind of artifact this is. v0.11.0 shipped on 2025-09-10 with a release note titled around float FMA versus integer DP4A and DPX instructions. v0.11.1 came on 2026-07-26 and v0.11.2 on 2026-07-27 with a title about optimizations, hardening and clarifications. The last push was on 2026-07-27.

So the practical maintenance picture is a snapshot. The project is not archived, but it is also not on the multi-week release cadence that a library dependency would need. If you depend on less_slow.cpp as a submodule, you are depending on a corpus whose last recorded activity was on 2026-07-27, and whose comments describe a state of the art that moves.

## Conclusion

Adopt less_slow.cpp if you are the kind of C++ developer who has opinions about `std::sin` and wants reasons for them, because the value is the commentary attached to each measurement rather than any single number. Do not adopt it as a dependency, and do not quote its figures as benchmarks for your own machine: the README states plainly that the benchmarks do not cover every topic, and the same 3x3x3 versus 4x4x4 result will not reproduce on hardware whose register file and vector width differ. Verify three things before spending an afternoon: that GCC on Linux is what you have, since the README recommends it for the broadest functionality and suggests WSL on Windows or a Homebrew or MacPorts Clang on macOS, that `liburing-dev` and a numerics library are installable in your environment since the build needs them for the kernel-bypass and BLAS sections, and that the code compiles as C++20 at all on your toolchain. The repository is Apache-2.0 licensed and the last push was on 2026-07-27 with v0.11.2 shipping the same day, which means it is a snapshot rather than a moving target: treat every comment as dated.

## FAQ

### How do I build and run the less_slow.cpp benchmarks?

Clone the repository, install build tools plus `liburing-dev` and `libopenblas-base`, then run `cmake -B build_release -D CMAKE_BUILD_TYPE=Release`, `cmake --build build_release --config Release`, and execute `build_release/less_slow`.

### Which compilers and platforms does less_slow.cpp support?

The project aims to be compatible with GCC, Clang and MSVC on Linux, MacOS and Windows, but is designed primarily for GCC, Clang and NVCC on Linux, and the README recommends GCC on Linux for the broadest functionality.

### Why does less_slow.cpp pull in range-v3 and libunifex?

range-v3 replaces `std::ranges` and libunifex provides senders and executors, so the corpus can compare against implementations other than the standard library ones. OneTBB serves as the Parallel STL backend and Google Benchmark does the profiling.

### Is less_slow.cpp a library I should depend on?

It is presented as a collection of benchmarks and explanations for building intuition about performance, not as a reusable library, and the README says the measurements do not cover every topic. The related `less_slow.rs` and `less_slow.py` repositories cover other languages.

### What license does less_slow.cpp use?

Apache-2.0, with the LICENSE file at the repository root and a CITATION.cff for academic citation.

### What does less_slow.cpp need for the io_uring sections?

The build instructions include `sudo apt-get install -y pkg-config liburing-dev`, which provides the kernel-bypass library used by the user-space networking sections.

## Sources

- [ashvardanian/less_slow.cpp on GitHub](https://github.com/ashvardanian/less_slow.cpp)
- [License: Apache-2.0](https://github.com/ashvardanian/less_slow.cpp/blob/main/LICENSE)
- [Project website](https://ashvardanian.com/tags/less-slow/)
- [README](https://github.com/ashvardanian/less_slow.cpp/blob/main/README.md)
- [Releases](https://github.com/ashvardanian/less_slow.cpp/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ashvardanian-less-slow-cpp
