RSSAmplifier

Blog

Neil Henning

Recent content on Neil Henning

neilhenning.devRSS feed ↗100 posts

Latest posts

I'm Allowing AI Use in my Libraries

I’ve taken the decision to allow AI use for PRs to my libraries. I personally believe these tools can be a net add (with lots of straight jackets and caveats), but I also think we’ve reached a point where I can’t really be sure whether the incoming PR requests are from people using AI tooling to help them, or just free roaming OpenClaw instances that are masking their AI nature…

Five Stages of Grief With the Rise of AI

I tried copilot in VS Code sometime in 2025 and was thoroughly disappointed with its ability. It felt like a really bad auto-complete at best, making plenty of mistakes and generally being utterly irritating to actually use with its need to constantly pop in as I was typing with long form coding suggestions that were often wrong. I was already predisposed to being negative about AI due to the…

I [[musttail]] You About a Tokenizer

One thing I’ve never really messed with before is the [[clang::musttail]] compiler attribute. Tail calls are when you exit a function by calling another function as the final thing within the function. For example: int foo(float x); int bar(float x) { x += 42.0f; return foo(x); } In the above example, foo is a tail call within the function bar . Compilers can take advantage of this by doing…

Custom asserts in LLVM

I tried (and failed) to convince the LLVM folks to allow for runtime togglable asserts . No biggie - the people much more involved with maintaining upstream didn’t want to have yet another codepath to maintain. They said that it’d cost 20% runtime performance to have asserts enabled, and that this cost would likely still be paid even if I did have asserts compiled off at runtime. Why…

Your Own Constant Folder in C/C++

I was talking with someone today that really really wanted the sqrtps to be used in some code they were writing. And because of a quirk with clang (still there as of clang 18.1.0), if you happened to use -ffast-math clang would butcher the use of the intrinsic. So for the code: __m128 test(const __m128 vec) { return _mm_sqrt_ps(vec); } Clang would compile it correctly without fast-math: test: #…

Verse Transactional Memory

When I interviewed for Epic Games it was for a graphics post - I wanted back to working on shader compilers. But even though most of my interviews were from the fantastic graphics side of the company, I had a few interviews about something I knew very little about - the Verse language. And on one of those interviews I was asked about something I hadn’t thought about for 15 years -…

Updating GitHub repos to Apple Silicon

I’ve updated my C/C++ open sources libraries utest.h , utf8.h , ubench.h , hashmap.h , subprocess.h , and json.h to use the new Apple Silicon GitHub CI runners. So how hard is it? Simple! You just add macos-14 to the build -> strategy -> matrix. I took the opportunity to drop macos-latest (which is still set to macos-13 , the last x86 runner) and explicity use the oldest supported macos-11…

How long does it take to compile LLVM 17 on a Raspberry PI 5

So I got my Raspberry PI 5. And like in my previous post , I compiled LLVM 17 on the Raspberry PI 5, and have compared the compile speed versus the Raspberry PI 4. I’m going to do the same steps: Compile LLVM using the default clang got via apt-get. Compile LLVM again using the clang we just built. And compile it a third time with the clang we built with our own clang (this step should be…

How long does it take to compile LLVM 17 on a Raspberry PI 4

With the imminent launch of the Raspberry Pi 5 I wondered - how long does it take to compile the latest LLVM release (17 at the time of writing this blog) on the Raspberry Pi 4. This will give me a baseline that I can test the Raspberry Pi 5 against once I get ahold of it. For my initial exploration I decided to test just three things: Using the stock Clang compiler I could get at via apt get to…

My Take On Return To Office and Remote Work

The Return to Office episode of one of my favourite podcasts Dithering made me finally decide to post about Remote Work. I’ll be back to my irregular coding posts soon, but I wanted to get this off my chest. Let me get all the caveats out the way - I worked in an office full time for the first five years of my career, and have now been working remotely for nine years. You could argue that…

How costly is changing the hardware rounding mode?

I was looking at hardware rounding modes the other day, and one thing that I realised I had no concept of was how costly is it to change the hardware rounding mode for floating-point operations. For those that don’t know - modern hardware often includes a way to set the rounding mode that floating-point operations use when there is an imprecision in the result of a floating-point operation…

New Web Domain & Mastodon Handle

This all started when I wondered what the Mastodon migration process between accounts was like, and ended with me moving my mastodon over to a new handle @neilhenning@mastodon.gamedev.place , and my website over to a new domain https://www.neilhenning.dev/ . I remember maybe two or three years into Twitter trying to change my handle over to be my name, and it was already taken. It always irked me…

Using Fibonacci Hashing in hashmap.h

I’ve been noodling a lot with my single header C/C++ hashmap recently - hashmap.h . I knew from reading around that the power-of-two size requirement I had meant that it made getting a bucket location in the range was easy, but that it could result in suboptimal bucket selection. Various places on the interwebs said that using a prime number hash was better as doing the modulus by a prime…

Making Hashing Faster in hashmap.h

One of the C/C++ single header libraries I maintain is hashmap.h . This library is a super light weight and easily integrated hashmap - I’m not focused on the performance necessarily here, it’s really there primarily as a nice-to-use hashmap for when you just want to throw something in there. But that doesn’t mean I want the performance to suck either. If I can make it faster…

New Year Cleanup

As a new year starts I generally have some long awaited cleanup to do on my C/C++ single header libraries. Maybe I need to update the CI scripts because they are out of date, maybe I have some features I want to add, or maybe I want to test more things. For those that do not know I have six main libraries that I maintain that are single header and work across C/C++: 🧪 utest.h - a single header…

I'm Pretty Much Done With Twitter

TL;DR - I’m pretty much done with Twitter (here-in named the “birdshite” 🦤💩). Let’s be honest - Twitter wasn’t exactly ideal for a pretty long time. The sheer amount of ads that were pushed into the feed even long before Space Karen bought the birdshite wasn’t great. I had already blocked thousands of accounts that were pushing promoted tweets into my feed,…

I've Joined Epic to Work on Verse

After four relaxing weeks off since I left Unity , I’m pleased to announce I’ve joined the Verse team over at Epic. Today was my first day, so obviously this is the day that I feel the most like an impostor! I’ve done this a few times now (jumping contract to contract when I worked at Codeplay, and then moving to AMD, Unity, and now Epic), and the feeling always passes once you…

Floating Point Compression Revisited

In a previous post I looked at floating-point compression, and it generated quite a lot of interest on Twitter, with lots of people suggesting things. So I haven’t tried them all (only the first few that people suggested), but I thought I’d present the results I did try. First, the chart! There was three different approaches that I looked at with this chart. zfp One thing that was…

I'm Leaving Unity

After three years of work at Unity I’m leaving the company, today being my last day. I’m immensely proud of the work I did to make Burst and HPC# so powerful for our users both within and outwith Unity, and to have worked with some really great people along the way. I fulfilled a lifelong ambition to work closely with some heroes of mine like Andreas Fredriksson , Daniel Collin , Cort…

Floating Point Compression - How Small Can We Get?

Editors prefix: I originally penned this in September, but got cold feet that I had somehow missed something crucial in my investigations, impostor syndrome reared its head, and I binned the post. But after being involved in a tweet thread about the compressibility of these tables, I’m gonna just publish my potentially flawed work incase someone notices something obvious! Having implemented…

LLVM 15 Compile Time With Burst

With the Burst compiler that I work on here at Unity, we use LLVM to produce highly performant codegen from the High Performance C# (HPC#) subset that we compile. We keep Burst actively supported all the way back to LLVM 10, so it means that I can always get an idea of the performance improvements (or regressions) that occur between LLVM versions. I’ve used a big internal project that…

Adding UTEST_SKIP to utest.h

A nice little feature I’ve just added to my single header C/C++ unit testing library utest.h is the ability to skip a test case. The motivation for this feature is from a user request , and it makes sense in the context that sometimes you might be refactoring some code, or designing a new feature, and the tests aren’t quite ready yet. You don’t want to comment out or delete the…

Making the LLVM Legacy Pass Manager 1.65x Faster

One of the things I was going to talk about in my COVID cancelled EuroLLVM 2020 talk was about a neat little trick we used to get the LLVM legacy pass manager to be significantly faster. So just in time for the legacy pass manager to finally sail off into the coding afterlife I thought I’d share the trick. TL;DR running less passes makes things compile faster. The longer version requires a…

Switching subprocess.h to posix_spawn

My single header C/C++ cross platform sub-process interaction library subprocess.h was designed using fork() on Linux/macOS. But a little birdie told me that I should be looking into using posix_spawn() instead as it was faster. TL;DR - I’ve switched the library to use POSIX spawn . There are various reasons fork can be slow , so how does my library fare? This is running on my MacBook Air…

Updated Website Theming

One ongoing complaint since I moved from wordpress to hugo around three years ago was that the theming I decided on wasn’t the best. It was dark mode only, I used a non-serif font for the blog post contents making it harder to read, and the reader mode didn’t work right either. So I’ve attempted (and most likely failed) to switch over to a light mode theme, used the lovely…

A Review of the Zig Programming Language (using Advent of Code 2021)

I’ve long thought that Zig was an interesting programming language, potentially more interesting than Rust in many respects given that Zig seems to be targetting a more modern C-like language replacement whereas Rust firmly looks like it is trying to take C++ out back like ol’ yeller. Rust is powerful, but the language is complicated , and no I’m not talking about the…

Porting Burst to the New LLVM Pass Manager

Last week the Burst team shook up our day-to-day schedules with the opposite of a Unity classic - the hackweek. Unity has a strong culture around taking a week or two a year (once with the whole company, maybe once with your team), to hack on something that you think might be an interesting avenue for the future of Unity. These projects have often been spun out into products or parts of products…

Introducing envcache

One thing that has always bugged me with Rust is when you are interacting with complex non-Rust software. Yes LLVM, I’m looking at you! LLVM nearly always requires you to either a) have llvm-config on the path already, or b) find an LLVM install in some random place on the filesystem. I generally like to have a version of LLVM built myself (using RelWithDebInfo and forcing asserts on) that…

Early 2021 Mega Update

The last four years of my coding life have been incredibly stressful. In this time I’ve: Started a job at AMD in the GPU compiler team. Left a job at AMD for Unity in the Burst compiler team. Wrapped up my involvement as a creator of Vulkan and SPIR-V. Learnt the C# and Rust programming languages. You couple this with the absolute trainwreck that was 2020 (COVID yay) and now it looks like…

How I Structure My Working Day

The more I’ve delved into the darkest corners of optimizing compilers, the more that incessant urge to optimize things has leeched out into my day to day life. I’ve found myself ever more obsessed over what the most optimal method to do things is. A few examples: While brushing my teeth twice a day I know I have a full two minutes where I can make use of my spare hand to do things.…

Advent of Code 2020 - Review

I’ve always wanted to do the Advent of Code 2020 puzzles as a way to wind down in the run up to Christmas, but never quite got my act in gear to do it. This year I’ve changed that, and I’ve pushed all my solutions to my AOC 2020 repository on GitHub . I thought that now that I’ve completed the challenge, I’d do a review mostly of how I used Rust to complete the…

Advent of Code 2020

I’ve always wanted to do the Advent of Code 2020 puzzles as a way to wind down in the run up to Christmas, but never quite got my act in gear to do it. This year I’m changing that, and I’ve just pushed my 1st day’s solutions to my AOC 2020 repository on GitHub . Solution parameters aside: I’m doing this in Rust. I started writing it out in Zig but honestly the docs…

Exploring Hourglass APIs in Rust

There are two talks on APIs that I think every programmer should watch, learn, and study from: Designing and Evaluating Reusable Components from Casey Muratori . This absolutely wonderful talk is the fundamental source for how to design APIs. Hourglass Interfaces for C++ APIs from Stefanus Du Toit . This talk discusses having a rich API for users that is backed by a C API into proprietary code.…

Introducing hashmap.h

I asked on twitter the other day whether anyone had a hashmap that could work with string slices - parts of a string that are not null-terminated and thus have to have an explicit length to accompany the pointer. I didn’t get any responses on this so I commented with a follow-up that I had grabbed some code written a few years back by the awesome Pete Warden of Google fame, and morphed it…

Asynchronous Reading in subprocess.h

One hotly requested feature for my single header C/C++ process spawning and management library subprocess.h was the ability to read from the standard output or error of a spawned process while it was still executing. In this PR I’ve added support for this, but it requires some change of behaviour in your code if you want to use it. C FILE’s and Asynchronous Reading I use a really…

Adding fixtures to ubench.h

One thing that was missing from ubench.h (intentionally to keep the initial code drop simple) was fixtures. In this PR I’ve added them. So what are fixtures and why should you use them? What are fixtures? Fixtures are a way to setup and teardown state that doesn’t contribute to the timing of the actual benchmark itself: // First you declare a struct that contains the state you need.…

I'm now 99% Confident in ubench.h

So I recently created a new single header C/C++ library for benchmarking your code - ubench.h . It’s funny how as soon as you push something public you realise all the flaws in it - but that’s fine! Software (like people) should grow and develop as it gets older. The way I was trying to gauge the accuracy of the result from multiple benchmark runs was somewhat… broken. In this…

White Guilt and Juneteenth

I’m currently sitting at home on an unexpected days holiday - for Juneteenth. The high hiedyins of Unity wanted to give us some space to reflect as a company on the racial inequality in the world. And I’m sitting here feeling guilty as all heck. Why should I, as a peely wally white guy, benefit yet again from black voices rightfully pointing out the utterly unjust situation that we…

Introducing ubench.h

Ever since I worked on my amazing little single-header C/C++ library utest.h , which mimics enough of Google’s googletest framework but in a significantly leaner footprint (and a single header!), I’ve wanted something similar for doing benchmarking. Google has their own benchmarking library Google benchmark , but it fails a couple of key tests that I have for libraries: It isn’t…

Simple C Command Line Parser

I’ve been feeling a little overwhelmed by the languages I generally code in (C#, C++, Rust) and wanted to get my teeth into something a bit simpler again (obviously C!). One thing I’ve never been that happy with in C was the lack of a good command line argument parser. There is a great list of option parsers that @nothings has curated over the years, but most of them are C++, and the…

utest.h Now Supports Whole Program Optimization

A user of utest.h posted an intruiging issue that on an release build with Visual Studio my unit testing framework for C/C++, utest.h , no tests were being ran. But on a debug build they were. Before I even got to the issue they worked out that whole program optimization was causing the issue and closed it themselves. But this got me thinking - there is no reason why my library shouldn’t…

How to Test Rust Command Line Applications

Testing command line applications in Rust is something that I found was a bit of a grey area. The main documentation for Rust has a section Testing CLI applications by running them which explains how they suggest you test command lines applications: use std::process::Command; // Run programs use assert_cmd::prelude:: * ; // Add methods on commands use predicates::prelude:: * ; // Used for writing…

Fixed Up RSS

One thing I’ve unfortunately neglected for a little while now on my blog was the RSS feed - mostly because I didn’t have a clue how to make Hugo do it as I’d like. There was a couple of issues: Only the summaries of my posts were fed via RSS - not the full contents. I do not do any sort of content tracking on my site because I don’t want to foist vaporware like Google…

Lessons of a Remote Worker

Jumping into cold water is always a shocking experience. Being able to calm yourself, acclimatise to the temperature of the water - before you attempt to swim is how you survive. A ton of people worldwide have just plunged into the icy water of working from home, and since I’ve been doing this for six years I have some advice from the good and the bad of what I learned over the time. In this…

Extracting the json.h README.md Code Samples For Compiling

One thing that has always worried me with writing C samples in documentation for my single-header libraries is that you can’t be 100% sure that they will compile successfully. You can always extract them and run them, but you might change them and forget to re-test. Having this be automatic is so powerful. Rust has this feature built in to the ecosystem so that all code samples are testing…

C89 & Single Header json.h

I’ve been working on my various C/C++ single header libraries some over the Christmas break, and while I already did an update on my work , I decided to leave json.h for its own post. C89 Support One requested thing over the years has been C89 support, and I was reluctant to do this mostly out of sheer laziness. I’d have to convert a bunch of comments over and remove my use of long…

Some Miscellaneous Library Improvements

I’ve been working on my various C/C++ single header libraries some over the Christmas break, and I thought I’d just jot down the improvements I’ve made in a post. process.h -> subprocess.h I’ve had a long standing complaint that the name process.h conflicted with a Windows system header. I’ve decided (after a good three years of indecision mind you) to just rename the…

utest.h

Anyone who has used the googletest library with a complex C++ codebase will know how powerful this form of unit testing can be for productivity. While the library has a ton of features and is seriously powerful, there are a number of technical deficits that come with it: It only works with modern C++. It has a complex build system integration, with multiple source files and headers. The startup…

FPSCEV - Improving the Range Analysis

In this post, we’ll improve our floating-point scalar evolution (fpscev) to do a better job at evaluating the range of some of the more complex intrinsics we analyze. This post is the latest in a series about my experimentations with floating-point scalar evolution, you really want to read them in order: An Experimental Floating-Point Scalar Evolution Using Floating-Point Scalar Evolution to…

Farewell AMD / Hello Unity

Announcement time - today is my last day at AMD. I’ll be taking a few weeks off, before starting a new gig at Unity mid-July. It is also the end of my five year involvement in Vulkan & SPIR-V - having contributed to both specifications since 2014. I’ve very much enjoyed my time in this slice of the industry, but it was time for a new challenge. Farewell AMD I’ve been at AMD a…