C++ - Reddit
228 subscribers
48 photos
8 videos
25.3K links
Stay up-to-date with everything C++!
Content directly fetched from the subreddit just for you.

Join our group for discussions : @programminginc

Powered by : @r_channels
Download Telegram
registers of 4 floats to memory, but advance the cursor only by `cnt`.
`compress` stores valid elements at the front of the register, at `[j, j + cnt)`, and garbage at `[j + cnt, j + 4)`.
The next iteration will start at `j + cnt` and overwrite the garbage from the previous step.
Garbage will remain only in `out[cnt, n)` after the last store.
We don't go out of bounds because the cursor never overtakes the elements that have been read.

## The `copy_if` loop

```cpp
auto copy_if_neon(const float* __restrict a,
float* __restrict out,
float threshold,
size_t n) {
auto thd = vdupq_n_f32(threshold); // load threshold into a register
size_t j = 0;
for (size_t i = 0; i < n; i += 4) {
auto v = vld1q_f32(a + i); // load the current 4 elements of a into a register
auto mask = vcgtq_f32(v, thd); // compute the mask

auto [packed, cnt] = compress(mask, v);
vst1q_f32(out + j, packed); // store packed into out[j, j + 4). [j + cnt, j + 4) will hold garbage
j += cnt;
}
return j;
}
```

- `vcgtq_f32(v, thd)` - calculate elementwise `v[i] > thd[i]`. `cgt` - compare greater
- `vst1q_f32` - store 4 floats from a register into memory. `st` - store

## Result

| function | ms (cache) | GB/s (cache) | ms (DRAM) | GB/s (DRAM) |
|-------------------------|-----------:|-------------:|----------:|------------:|
| copy a[i] if a[i] > 0 | 0.0104 | 77 | 1.11 | 72 |
| copy a[i] if a[i] > 0.5 | 0.01063 | 75 | 1.13 | 71 |
| copy a[i] if a[i] > 1 | 0.01 | 80 | 1.06 | 76 |

\> 0.5 was the worst case for the scalar version, 3 GB/s. Now 71 GB/s. A more than 20x speedup.
Now there are no branches, so speed doesn't depend on data.

## Trick 2: calculating `idx` and `count` in a single `addv`

`idx` is always less than 16, so let weights = {1 + 16, 2 + 16, 4 + 16, 8 + 16}
and s = sum across mask & weights. Then s / 16 is the element count and s % 16 is `idx`.
So, we don't need to compute the `count` table.
`compress` now:
```cpp
auto compress(uint32x4_t mask, float32x4_t a) {
static constexpr std::array<uint32_t, 4> weights{1 + 16, 2 + 16, 4 + 16, 8 + 16};
const size_t s = vaddvq_u32(vandq_u32(mask, vld1q_u32(weights.data())));
const size_t count = s >> 4; // same as s / 16
const size_t idx = s & 15; // same as s % 16

static constexpr auto index_table = make_index_table();

const auto index = vld1q_u8(index_table[idx].data());
return std::pair{vreinterpretq_f32_u8(vqtbl1q_u8(vreinterpretq_u8_f32(a), index)), count};
}
```

And now the speed climbs again:

| function | ms (cache) | GB/s (cache) | ms (DRAM) | GB/s (DRAM) |
|-------------------------|-----------:|-------------:|----------:|------------:|
| copy a[i] if a[i] > 0 | 0.0095 | 84 | 1.015 | 79 |
| copy a[i] if a[i] > 0.5 | 0.0095 | 84 | 1.007 | 79 |
| copy a[i] if a[i] > 1 | 0.0096 | 83 | 1.008 | 79 |

## Unroll

We can squeeze out more speed by unrolling the loop 4x (16 elements per iteration):

| function | ms (cache) | GB/s (cache) | ms (DRAM) | GB/s (DRAM) |
|-------------------------|-----------:|-------------:|----------:|------------:|
| copy a[i] if a[i] > 0 | 0.0081 | 98 | 0.882 | 91 |
| copy a[i] if a[i] > 0.5 | 0.0083 | 97 | 0.892 | 90 |
| copy a[i] if a[i] > 1 | 0.0082 | 97 | 0.869 | 92 |

Final code ([godbolt](https://godbolt.org/z/n8E6ocKoj)):

```cpp
consteval auto make_index_table() {
std::array<std::array<uint8_t, 16>, 16> index{};
for (size_t idx = 0; idx < 16; ++idx) {
size_t j = 0;
for (size_t i = 0; i < 4; ++i)
if (idx & (1 << i))
for (size_t k = 0; k < 4; ++k)
index[idx][j++] = i * 4 + k;
}
return
index;
}
auto compress(uint32x4_t mask, float32x4_t a) {
static constexpr std::array<uint32_t, 4> weights{1 + 16, 2 + 16, 4 + 16, 8 + 16};
const size_t s = vaddvq_u32(vandq_u32(mask, vld1q_u32(weights.data())));
const size_t count = s >> 4;
const size_t idx = s & 15;

static constexpr auto index_table = make_index_table();

const auto index = vld1q_u8(index_table[idx].data());
return std::pair{vreinterpretq_f32_u8(vqtbl1q_u8(vreinterpretq_u8_f32(a), index)), count};
}
auto copy_if_neon_unroll(const float* __restrict a,
float* __restrict out,
float threshold,
size_t n) {
auto thd = vdupq_n_f32(threshold);
size_t j = 0;
size_t i = 0;
for (; i + 16 <= n; i += 16) {
#pragma unroll
for (size_t i0 = 0; i0 < 16; i0 += 4) {
auto v = vld1q_f32(a + i + i0);
auto mask = vcgtq_f32(v, thd);
auto [packed, cnt] = compress(mask, v);
vst1q_f32(out + j, packed);
j += cnt;
}
}
for (; i + 4 <= n; i += 4) {
auto v = vld1q_f32(a + i);
auto mask = vcgtq_f32(v, thd);

auto [packed, cnt] = compress(mask, v);
vst1q_f32(out + j, packed);
j += cnt;
}
return j;
}
```
`tbl` and the index table provide `compress`, something that NEON doesn't have out of the box.
This isn't just about `> threshold`. Filter, remove and other data-dependent functions are built the same way.


https://redd.it/1uqscnr
@r_cpp
Interesting behavior from C++20 to C++23

Consider the following snippet

int& get()
{
    int x;
    return x;
}


int main()
{
}

on GCC it compiles for C++20 but not for C++23

It returns with the error:

test.cpp:4:12: error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'

C++ is now suddenly treating the variable x as an rvalue?


Edit: Im not talking about dangling reference, thats just for the sake of the example

https://redd.it/1usgvun
@r_cpp
Trying to create a paper piano

Trying to create a paper piano

I came across many paper piano projects where they detect finger and paper touch using opencv and some even use neural network but the problem still remains that it's not accessible for everyone. Some people still don't have computers or even laptops. So I thought about a paper piano project that uses only the mobile phone and itscamera and using a cheap phone stand to set the correct angle and a printed paper. So a mobile phone which most people have, an app to download for free and a mobile stand with a printed paper which altogether costs approx $ 2.5. The reason for this post is that I may not work on this project anytime sooner so if anyone wants to work on this project help yourself and if you come across some references or a project similar to this then add it in the comment.

https://redd.it/1uslas1
@r_cpp
Libraries of, installing, and depending on C++20 modules

Until now, much of the discourse around C++20 modules has been around the tooling, and actually getting modules to work at all. I believe that now, in mid-2026, the tooling is mostly mature: the three largest compilers support most use-cases of modules. IDEs like CLion, and lint tools like ReSharper C++ and clangd support modules, with some caveats. CMake, xmake, Ninja, and other fledgling build systems have full support for modules. Many prevalent C++ libraries and projects have been recently modularised or are in the process of modularising.

I hope I'm not being too presumptive in saying the community is more or less ready (albeit horribly late...) to move to the next step, and start discussing how C++20 modules can and should tie in to inter-project work, rather than simply using modules within a project.

To begin with, I don't think the standard says anything about 'libraries'; these are existing paradigms grandfathered in from C or earlier. There are many axes we have to discuss here:

- Static archives
- Dynamically-linked libraries
- Symbol visibility defaults with `__declspec( dllexport )`
- Primary module interface-only (hereafter, PMI) libraries such as `module vulkan`
- Configuring such modules with macros
- Built module interface (hereafter, BMI) and binary interface (hereafter, ABI) compatibility; currently, BMIs are simply not portable, not even within a compiler toolchain across versions
- How shared objects, static archives, BMIs, and PMIs interact
- How build systems, toolchains, and package managers like conan and vcpkg interact with everything

For instance, consider I'm writing a 3D game engine. I want the following modules:

- vulkan which export imports std
- argparse
- glm
- glaze
- quill, which imports fmt
- fmt itself
- winrt, if running on Windows

I want to provide my own PMI that has export class Engine, and maybe some other functionality like abstractions over the 3D graphics APIs, an object and entity manager, a mini shader graph generator, and more. I also have export imported some symbols from my dependencies, especially std. I want to choose to configure my engine to render on D3D or Vulkan. Consumers can then load the library, add assets like textures, meshes, skeletons, shaders; they can plug the engine into a bigger project which might include a script interpreter in C++, real-time spatial audio and physics packages, some networking, and an XML-based UI system, and produce a complete game or visualisation executable.

Now, I mention these details just to flesh out the example to give a sense of a reasonably complicated library-esque project.

How does one even think about delivering this 'engine library' to the consumer? The traditional three configs are headers + precompiled DLL, headers + source, or headers only. Each have their established workflows. Source-available can be compiled into the entire binary with whole-program optimisation; headers-only libraries are exceptionally easy to vendor (just copy-paste). Header-only libraries can also be easily customised with consumer macros. PMIs, however, being translation units, cannot; we hit this when installing `module vulkan`. We need some module-compatible way to describe 'library configuration' beyond simply co-opting macros, something like Rust's `cfg`.

There is talk of the Common Package Specification (CPS), P1689R5, and P3286, but nothing concrete yet, especially since there has been no massive (commercial) push for
modules (at least, not until recently). This talk at NDC looks at a possible cargo-esque future for C++.

I'm writing this to spur some discussion here in the C++ community, and ask what some veterans of the build system/toolchain/package manager community think.

https://redd.it/1ustebp
@r_cpp
What Made You Fall in Love With C++—and What Almost Made You Quit?

This is a great opportunity to share your life story as a C++ programmer: how you started, why you chose C++, what your first impressive project made purely for fun was, and what kind of job you do.

You can share all of that here!

I would also love to hear the criticism—the days when you wanted to escape from boring CRUD and API projects, as well as the happiest days of your life when you finally got the chance to work on your dream job.

https://redd.it/1uto7bm
@r_cpp
Building a tool for offline coding practice on flights/trips — would you actually use this?

Hey everyone,

I'm a developer working on a side project/startup idea and wanted to get honest feedback before I sink more time into it.

The idea: a website where you pick a programming language and a specific track (e.g., Go basics, or backend development with Go), and it generates a downloadable offline package — documentation, tutorials, and exercises — packed into a zip file. You download it before you lose internet access (long flight, train, remote area, wherever), and once offline you just open it in your browser like a normal site. No connection needed.

I know there are already tools like DevDocs, Dash, and Zeal that let you save documentation offline. What I'm trying to do differently is focus on structured learning tracks with exercises, not just a raw doc viewer — more like a self-contained mini-course you can work through with zero connectivity.

I'm trying to figure out monetization without doing a subscription (that already feels like the wrong model for something people might use a handful of times a year). Current thinking is one-time purchase per track, or eventually partnering with airlines.

Genuine questions for you all:

1. Would you pay a small one-time fee for something like this? (like 5 dollars)
2. Would you use it even if it were free — or does existing offline documentation (Dash, DevDocs, etc.) already solve this well enough for you?

Trying not to build something nobody wants, so brutally honest feedback is welcome. Thanks!

https://redd.it/1utrasf
@r_cpp
Looking for C++ / Systems / HFT Internship or New Grad Opportunities

Title: Looking for C++ / Systems / HFT Internship or New Grad Opportunities

Hi everyone,

I'm currently looking for Software Engineering Intern, C++ Developer, Systems Programming, or HFT/Low-Latency Engineering opportunities.

Over the past year, I've focused heavily on C++, Linux, competitive programming, and building projects that pushed me beyond my comfort zone.

A few highlights about my profile:

Codeforces Specialist
CodeChef 4★
Strong foundation in DSA and Modern C++
Comfortable with Linux, Git, and CMake

I've built two major C++ projects:

A systems programming project focused on low-level software engineering and performance.
A low-latency order book/trading systems project that has received 50+ GitHub stars and valuable feedback from engineers with HFT backgrounds, including people associated with firms like IMC Trading and Jane Street. Their suggestions helped me improve both the project and my understanding of high-performance systems.

I'm particularly interested in roles involving:

High-Performance C++
Systems Programming
Backend Engineering
Low-Latency Infrastructure
Distributed Systems
Quant/HFT Technology

I'm always eager to learn, take on challenging engineering problems, and contribute to real-world systems.

If your company is hiring interns or new graduates, or if you know of any opportunities that match my profile, I'd greatly appreciate any referrals, advice, or connections.

Feel free to DM me if you'd like to connect.



https://redd.it/1utud1j
@r_cpp
i had to port my odin game to cpp

i finally got the game working in web but it doesnt look right butler status rawptr/hexbound:html5 i had to use butler and port from odin to c https://rawptr.itch.io/hexbound

https://redd.it/1utz54e
@r_cpp
GoCL – A C++20 Vulkan proxy with zero‑overhead dispatch, SPIR‑V rewriting, and lazy‑loaded backends

I’ve been working on a Vulkan optimisation layer and static library called GoCL. The C++ side ended up more interesting than I expected, so I wanted to share a few design choices.

It’s a Vulkan proxy (vulkan_proxy.so / vulkan‑1.dll) and a static library (GoCL_core.a) that adapts rendering to the GPU’s actual capabilities at runtime. The proxy intercepts Vulkan calls and modifies them before they reach the driver, while the static library provides the same logic directly to engines that link against it. All C++20.

C++ details that might interest this sub:

Capability oracle – on device creation, the engine queries every relevant physical device feature (texture compression, float16 support, descriptor indexing tiers, memory budget, etc.) and stores the result in a plain `DeviceCapabilities` struct. Every subsystem reads from that struct; there’s no virtual dispatch or runtime capability checks on the hot path. Decisions are data‑driven and branch‑predictable.
Proxy dispatch chain – the proxy hooks Vulkan entry points by patching a dispatch table (the loader’s vkGetDeviceProcAddr pattern). The table is populated at vkCreateDevice time. On Linux the library is linked with -Wl,-z,now so all dynamic symbols are resolved eagerly at load time. Callgrind confirms zero lazy‑binding overhead in the render loop – dlopen/dlsym calls appear only in initialisation functions.
SPIR‑V rewriting – unsupported shader features (FP16, oversized descriptor sets) are detected and the binary is rewritten before the driver sees it. The rewriter is a lightweight in‑memory pass that widens FP16 ops to FP32 and splits large descriptor bindings. No external compiler, no LLVM dependency; it’s just a handful of C++ functions operating on the SPIR‑V binary blob.
Lazy‑loaded transcoder – the heavy Basis Universal encoder (used for ASTC→ETC2 texture conversion) is separated into gocl_transcoder.so, loaded via dlopen / LoadLibrary only when an ASTC texture is encountered. The static initialisers of the transcoder are therefore never invoked unless actually needed, keeping the proxy’s baseline footprint minimal.
Zero per‑frame overhead – Callgrind instruction counts on a GTX 960M running 75+ Sascha Willems Vulkan examples: the proxy has \~3.8% fewer total instructions than native (3.806B vs 3.955B). FPS and frame times are identical within noise. All the work happens once at pipeline creation or texture load; the render loop is untouched.
Dual‑licensed under Apache‑2.0 OR MIT. Tested in CI with Mesa Lavapipe.

Architecture write‑up (covers the capability model, shader emulation, proxy internals, and the lazy‑load design):
GoCL – Architecture

GitHub: GoCL

Happy to discuss the C++ side – the capability oracle and the SPIR‑V rewriter in particular were fun to keep simple and predictable.

https://redd.it/1uu3392
@r_cpp
AFXDP implementation in C++ plus benchmarks against DPDK on real NICs

I developed a C++ library which implements AF\
XDP and DPDK as backends for latency critical network processing tasks. I notice there are only few benchmarks comparing AF_XDP against DPDK on the same NICs therefore I aim to fill this gap. I used C++20 since that is my strongest language and it interfaces nicely with the low-level driver or linux kernel code.

The AF_XDP implementation is here: https://github.com/ASherjil/ABTRDA3/blob/master/src/backends/AF\_XDP/AFXDP.hpp


The comprehensive benchmark 24h results are here:

https://github.com/ASherjil/ABTRDA3/blob/master/docs/Benchmarks.md

One point that I think is underappreciated: a commonly marketed advantage of AF_XDP is that it doesn't unbind the NIC driver, so the interface stays visible to ip link and ethtool. That's true for Intel NICs, where DPDK requires binding to vfio-pci. But it's not true for mlx5 (ConnectX-4/5/6/7), which is a bifurcated driver — the NIC stays fully visible to the kernel while DPDK runs. On Mellanox hardware, the main practical argument for AF_XDP largely disappears.

On implementation effort: even with libbpf and libxdp, custom AF_XDP has high code complexity and plenty of driver-specific quirks. Its four lock-free SPSC rings (fill/RX/TX/completion) are counterintuitive and fairly difficult to comprehend. Without the helper libraries I'd call it a serious long-term project. For most use cases I'd recommend DPDK's AF_XDP PMD instead of a from-scratch implementation — in my results, my custom implementation performed only marginally better than DPDK’s AF_XDP PMD. I've documented the driver specific issues in the repository.

Let me know if you guys have any feedback about the code, bench-marking methodology or anything else. Or any questions I'm happy to answer I don't really mind.

https://redd.it/1uub2kx
@r_cpp
Upa URL parser library v2.5.0 released

* Aligned with the most recent revision of the [WHATWG URL Standard](https://url.spec.whatwg.org/).
* Implemented [URL Pattern Standard](https://urlpattern.spec.whatwg.org/).
* Added support for compiling as a [C++20 module](https://github.com/upa-url/upa/blob/main/doc/modules.md).

More information: [https://github.com/upa-url/upa/releases/tag/v2.5.0](https://github.com/upa-url/upa/releases/tag/v2.5.0)

https://redd.it/1uuf1bl
@r_cpp