Hacker News

Top stories

Live mirror
30 storiesupdated just nowView source snapshot
  1. The Normalization of Inexplicable Failures (ihatethefuture.com)
    32comments
  2. In an $80 Motel Room, a Discovery to Shed Light on the Origins of Life (nytimes.com)
    32comments
  3. Ten Lines of Code That Changed My World (pixelambacht.nl)
    15comments
  4. Writing Efficient C++ Code (asawicki.info)
    26comments
  5. Replacing the old battery on rechargeable bike lights (jvns.ca)
    35comments
  6. Show HN: TinyAIArena watch AI agents battle it out (tinyaiarena.com)
    18comments
  7. There are no "rogue" AI agents (eoinhiggins.substack.com)
    47comments
  8. Walgit: A Git server that is one binary in front of an object store (github.com/rgodha24)
    4comments
  9. Flip Fluid on Flip Dots (mitxela.com)
    19comments
  10. Fakecloud: Local AWS cloud emulator for integration tests (fakecloud.dev)
    32comments
  11. The Cartesian Hand: In-Hand Manipulation with All-Linear Fingers (generalroboticslab.com)
    —discuss
  12. postmarketOS Rebrand: Nura (nura.eco)
    8comments
  13. Does Georgism work? Five years later (astralcodexten.com)
    388comments
  14. Go Concurrency Distilled (antonz.org)
    136comments
  15. Show HN: A CC0 museum of retro 3D tricks you can paste into a page (3d-retro.com)
    10comments
  16. Finally, A True Blue Rose Exists (sciencenews.org)
    29comments
  17. PipePipe: NewPipe hard fork implementing SponsorBlock (github.com/infinityloop1308)
    257comments
  18. Installing NeoVim caused original Vim undo files to be deleted (aresluna.org)
    231comments
  19. Rusty thoughts on "Parse, don't validate" (thegreenplace.net)
    17comments
  20. Unsealed Briefs in Authors’ Case v. Microsoft/OpenAI (authorsguild.org)
    522comments
  21. The internet discovers TLA+. Now what? (reasonable.io)
    47comments
  22. Show HN: Reladraw – A diagram language where you decide where to place things (github.com/reladraw)
    101comments
  23. DeepSeek Elastic Compute (DSec) (arxiv.org)
    97comments
  24. OpenAI halts training of latest models as reports mount of AI agents going rogue (theguardian.com)
    45comments
  25. Biology might not be quantum, but its math is quantumlike (quantamagazine.org)
    47comments
  26. "As a Language Model": Chat Template Switches LLM Self-Referential Voice (arxiv.org)
    94comments
  27. A searchable library of forgotten public-domain film clips from 1915 onward (movingimagearchive.com)
    27comments
  28. 10 Tells of a Slop UI (hereticpleb.vercel.app)
    169comments
  29. An agent used DNS to reach an external chatbot (alignment.openai.com)
    151comments
  30. Exploding variance of means of exponentials: least-squares to the rescue (francisbach.com)
    —discuss

Writing Efficient C++ Code

67 pointsby 1d agoasawicki.info
24 comments
2h agoHN ↗

"This article was originally published in Polish in issue 4/2013" — a lot of excellent advice. Sad to see C++ have moved in last decade in a direction that makes writing efficient, simple low level code harder and harder :(

1h agoHN ↗

How? you can write exactly the same low level code today.

1h agoHN ↗

My thought too.

There are so many things that are expressible in C++ now that could not be without writing much more code or using per-compilation tools back then. The ability to run code at compile time that is not run at runtime is huge, #embed lets us make other tools output available without linker scripts or compiler specific tools that.

Also, most of the code from the past still works(from 10 years ago definitely works)

1h agoHN ↗

Shot in the dark, but maybe the OP is referring to the fact that these code conventions are explicitly discouraged by the C++ core guidelines. The SoA example falls afoul of the rule requiring T* to be used only for singular object pointers, for example.

1h agoHN ↗

Not a regular C++ programmer but wouldn’t you use std::span here instead? Sure it’ll carry a few redundant lengths but it makes using functions that take spans easier. When I do write C++ it’s usually for speed so I’m often working at the intrinsics level, though AI has gotten good enough at it that I now generally delegate this work to an agent.

31m agoHN ↗

Depending on the specific code, the compiler may even eliminate the redundant lengths.

1h agoHN ↗

I think it has become EASIER: for instance, since C++23 Rust-like move semantics can be used, which provides the compiler with extra information that can be leveraged for the generation of better code.

Or take constexpr - it permits to move computations to compile time that are complex and in older versions either had to be done at runtime, or an ugly workaround had to be used (e.g. assigning a mysterious literal pre-computed in another run or by hand).

1h agoHN ↗

C++23 Rust-like move semantics can be used

What C++23 feature allows that?

25m agoHN ↗

Writing clear, concise, and efficient code in C++ has never been simpler or easier. The improvements in C++ over the last 15 years have been qualitative.

So many complex, esoteric, and difficult to maintain incantations that used to be required for efficient code generation are no longer necessary.

1h agoHN ↗

I write in C++ almost every day but never have the need to optimize for speed. Even when you write straightforward code it's already blazingly fast.

1h agoHN ↗

I rarely use C++ but when I do it is for speed. It’s not uncommon that carefully crafted intrinsics can 10x the straightforward naive implementation.

1h agoHN ↗

It is probably very domain specific. In robotics for example everything is a zero sum game: CPU, memory bandwidth, GPU, battery life etc ... So it is really a topic, probably true for anything embedded actually. Some other offline applications: HFT, Telco etc.. I wish the GUI apps devs respect more the laptop resources they are running on, don't get me started on the 4 instances of chrome I need to run just for discord, signal etc ...

33m agoHN ↗

True, but moving from a list of unique polymorphic pointers to a std::variant gains you at least a 2-3x speed up in terms of TLB and cacheline locality. From there, swapping to SOA will net you another 4-8x, so you're looking at nearly 25x improvement by going data first. That may not matter in the unique case of say, games, where rendering a million entities will dwarf the cost of SIMD processing a million entities, but in something like numerical simulations (fluids) or quant it will be warmly welcomed

23m agoHN ↗

Is the improvement from using std:variant vs polymorphism just due to the indirection you save on?

5m agoHN ↗

When writing code for end-user applications, I think it's mostly true. When it's writing code for a database engine, a game engine, a 3d renderer, or anything else that involves heavy data processing, optimization is the core "thing" often and it might not even be a good enough solution without it. Although, a lot of time even then C++ is good enough even then when picking reasonable data structures to represent the data.

4m agoHN ↗

I started writing a 3-D rendering library in C++, after having written the equivalent in C. The reason I decided to write it in C++ after C, is not only because I wanted to tap into meta-programming which is facilitated much better with C++, or that I wanted niceties like procedure overloading, but because some things with C++ (or C) aren't automagically optimised -- like if you want to leverage struct-of-array (SoA) memory layouts because it lends to fewer SIMD (AVX in my case) instructions in the rendering pipeline, you do _not_ get that "for free" just writing a single procedure in C++, much less with C. Bot languages are layout-sensitive, I mean this is in part what gives one the speed -- optimising with memory layout for cache locality etc. But you have to do it yourself. Meaning that if you need array-of-struct (AoS) or in fact don't know which path the CPU would prefer, there's no other way than roll up your sleeves and one way or another implement both.

The kicker is, in my case I chose C++ because templates allow me to reuse most of the code in the rendering pipeline _regardless_ of whether I go for AoS or SoA layout. I leverage operator overloading to do vector by matrix multplication which is implemented in both variants. I do have to specify the desired variant during building, but I've profiled and for Intel x86 and AVX in my case SoA is an order of magnitude improvement, so I just use that.

TL;DR; C++ gives you plenty fast by default, but it's not always enough. The difference between 15 and 45 frames per second is the difference between raw and baked (if it was bread).

1h agoHN ↗

There's no mention of branch prediction, or context switching, or synchronisation. Depending on what you're doing, they could be very consequential. There's only very brief mention of parallelisation with threads and with SIMD.

High-performance programming is a big topic. The scope is far too broad for a single blog post, which naturally gives only cursory discussion of C++ and computer architecture. The article isn't bad considering, but I do think it's the wrong format. A blog series, or even a book, would be more fitting.

39m agoHN ↗

Learn which instructions SIMD nicely (sqrt / fabs, etc). Use ternaries in loops for masking. Use trig identities and lookup tables (don't recompute sin(3t) when you can use two vector multiples using a table of sin(t) eg. sin(t) * sin(t) * sin(t)). Use divisible constexpr constants in loops to eliminate the SIMD tail. Be careful with type casts and floats. `float x; x += 0.5` will introduce *cvt instructions even if the compiler statically knew better otherwise (use 0.5f). Compile with --fast-math and friends so errno doesn't invalidate your SIMD pipeline.

27m agoHN ↗

Most applications (including most applications that care about numerical performance) should not use -ffast-math.

24m agoHN ↗

That has a similar problem to the article, it's trying to fit far too much into too small a format.

What you've written mostly makes sense to someone who already has a solid understanding of SIMD and of C++ (although I can't say I follow all of it), but the target audience is people who don't. For them, each point needs a much lengthier explanation.

22m agoHN ↗

My latest C++ project is assessment engine covering various actuarial type things like calculates risk for insurance etc. Typical performance for bulk calculation reaches millions to 10s of millions assessments per second on 16 core server. Well there is a trick there that inside it JIT compiles rules from a DSL to an executable code. interpreter mode (used mainly for audit mode) is about 3-5 times slower which is still insanely fast