<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/simd-for-collision-box2d-wsosdjqbv" -->

---
title: SIMD for Collision :: Box2D | daily.dev
description: Box3D (the 3D successor to Box2D) applies wide SIMD to the Separating Axis Test (SAT) edge-edge collision phase for complex convex hulls. For a 32-point hull...
canonical: https://daily.dev/posts/simd-for-collision-box2d-wsosdjqbv
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: SIMD for Collision :: Box2D | daily.dev
og:description: Box3D (the 3D successor to Box2D) applies wide SIMD to the Separating Axis Test (SAT) edge-edge collision phase for complex convex hulls. For a 32-point hull...
og:url: https://daily.dev/posts/simd-for-collision-box2d-wsosdjqbv
og:image: https://api.daily.dev/og/posts/wsOsdJQbV.png
og:image:alt: SIMD for Collision :: Box2D
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# SIMD for Collision :: Box2D

**[Lobsters](https://daily.dev/sources/lobsters)** · 6 min read · 0 upvotes · 0 comments

## Summary

Box3D (the 3D successor to Box2D) applies wide SIMD to the Separating Axis Test (SAT) edge-edge collision phase for complex convex hulls. For a 32-point hull with 89 edges, the inner loop grows to 7921 edge-edge tests, making SIMD worthwhile. By packing four edges of hull B into a single SIMD register (SSE2), the benchmark runs over 2x faster than scalar across 1–8 threads on an AMD 7950x. Enabling AVX2 architecture without a full AVX2 implementation yields additional free gains. The optimization has negligible impact on simple box-box collisions but significantly benefits complex hulls (e.g., destruction scenarios). A hard 128-edge limit in Box3D bounds the quadratic growth of SAT.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://box2d.org/posts/2026/07/simd-for-collision>

## Community take

How the wider developer community reacted, aggregated from 2 discussions and 11 comments across lobsters, hackernews (as of 2026-07-23).

**TL;DR:** The Lobsters community is enthusiastic about the Box3D SIMD collision post, using it as a springboard for a rich discussion on when and how to apply SIMD manually versus relying on auto-vectorization. The overall tone is positive and educational, with some nuanced debate about the limits of compiler auto-vectorization.

**Sentiment:** 75% positive · 20% mixed · 5% skeptical

**The case for**

- Basic SIMD for tight loops follows a simple, repeatable pattern that most developers can learn and apply for 2–16x speedups.
- Runtime dispatch libraries like Google Highway and language-level intrinsics (e.g., Zig) make portable SIMD more accessible.
- LLVM's auto-vectorization is already production-quality for simple array-processing loops and can deliver significant implicit speedups.
- SIMD can be applied directly to heterogeneous structs, not just arrays, enabling constraint processing on mixed types.

**The pushback**

- Auto-vectorization reliably handles only the simplest cases and cannot redesign data structures or algorithms to be SIMD-friendly.
- Portability across SIMD ISAs (SSE2, AVX2, AVX512, ARM NEON) is a major pain point with no effective single abstraction.
- Auto-vectorization is opaque—developers may unknowingly rely on it and be blindsided when a compiler change breaks it (one commenter saw ~70% slowdown from an LLVM regression).
- Some argue auto-vectorization is effectively AI-complete, explaining why decades of research have yielded only incremental gains.

**By community**

- lobsters (positive): Highly engaged thread with 37-point top comment offering a detailed SIMD tutorial; discussion is constructive and largely enthusiastic about manual SIMD with healthy debate on auto-vectorization limits.
- hackernews (mixed): No comments present, so no community signal beyond the 3 upvotes.

**Hottest debate:** Whether compiler auto-vectorization is 'good enough' for production use or remains fundamentally limited to trivial cases, with commenters split between praising LLVM's real-world effectiveness and arguing it is an AI-complete problem with decades of stalled progress.

**Open questions**

- How well is recent auto-vectorization research actually deployed in mainstream compilers like GCC and Clang?
- When does SoA vs AoS data layout meaningfully affect SIMD effectiveness, and are there good heuristics for choosing?
- Will AVX512's inconsistency across microarchitectures ever be resolved enough to make it a reliable SIMD target?

**Highlights**

> SIMD is surprisingly easy to reason about for tight tasks like this and more software people should be utilizing it. I think people get hung up on the crazy (and genuinely impressive) SIMD projects like simdutf and simdjson, which are head-spinning in complexity.  But basic "process N bytes at a time" SIMD that could speed up many ordinary loops are fairly simple! They all follow the same pattern: 1. Broadcast any constants you need and initialize vector accumulators, if any. 2. Loop over input one vector-width chunk at a time 3. Perform the comparison or arithmetic across all lanes in parallel. 4. Reduce or store the vector result as needed (into number 1) 5. Handle the remaining elements with a scalar tail. A scalar tail is just your _normal_ loop you had before vectorizing, but its only processing the remainder that doesn't fit into the vector-width. Here is a simple example. I have a byte string that I want to keep consuming until I see a value less than `0xF` (a control character limit). The naive loop: ``` // Loop while we see codepoints above 0xF while (end < cps.len and cps[end] > 0xF) {     end += 1; } ``` And here is the generic vector version (no CPU-specific intrinsics): ``` // If the target CPU doesn't have a vector size for u32 just fallback to // scalar. This has some CPU detection and hardcoding so we pick // the proper vector width for the hardware. if (simd.lanes(u32)) |lanes| {     // A vector containing `lanes` independent `u32` values. Basically a chunk of u32!     const V = @Vector(lanes, u32);     // Broadcast 0xF into every lane so one vector comparison checks every value.     const threshold: V = @splat(0xF);     // Only enter the SIMD loop when a complete vector remains in the input.     while (end + lanes <= cps.len) {         // Load the next `lanes` codepoints into a single SIMD vector.         const values: V = cps[end..][0..lanes].*;         // Compare every codepoint against 0xF in parallel, producing one boolean per lane.         const greater_than_threshold = values > threshold;         // When every lane is greater than 0xF, the entire vector can be skipped.         if (@reduce(.And, greater_than_threshold)) {             end += lanes;             continue;         }         // Convert the per-lane booleans into a bit mask: 1 means the value was > 0xF.         const mask: std.meta.Int(.unsigned, lanes) =             @bitCast(greater_than_threshold);         // Invert the mask so failing lanes become 1, then find the first failing lane.         end += @ctz(~mask);         // We found the first value <= 0xF, so the scan is complete.         break :scan;     } } // Finish the partial vector-sized tail, or do the entire scan when SIMD is unavailable. // It's just our normal scalar loop! while (end < cps.len and cps[end] > 0xF) {     end += 1; } ``` This gets you straight throughput speedup of anywhere from 2x to 16x depending on the hardware. This is real, because its from my actual project.  I realize that it looks like a LOT more code, but its code following a really specific pattern that you get used to quickly (the steps outlined above). And, the comments and whitespace add a lot of noise. :)  Why can’t the compiler just do this through auto-vectorization? Sometimes it can! Compilers are quite good at vectorizing simple, regular arithmetic loops. But you still can't reliably expect them to discover more complicated transformations like this one, particularly when the loop contains an early exit and the desired implementation involves a comparison mask, a reduction, and locating the first failing lane. More details here: https://llvm.org/docs/Vectorizers.html (always know your compilers!) You could say “compilers aren't good enough for now,” but auto-vectorization has been an active compiler research problem for decades, and recent research still begins from the observation that production compilers frequently miss vectorization opportunities. (Ref from 2024: https://arxiv.or
> — [mitchellh on lobsters · 37 points, 4 comments](https://lobste.rs/s/gkcjic/simd_for_collision#c_pwdpep)

> You can use SIMD directly on structs! A common use case is doing constraint processing on a bucket of heterogeneous types in parallel. The idioms for how to parallelize evaluation of independent constraints over different types are less obvious than using SIMD on arrays but it definitely works. I've shipped a few systems that worked this way and it was a massive speedup. Portability across SIMD ISAs and microarchitectures is a major pain. There are too many differences in capability, expressiveness, and performance to abstract them effectively, so you end up implementing different algorithms directly using the intrinsics. You will find narrow cases where e.g. AVX2 algorithms run faster than AVX512 algorithms on some microarchitectures that support both. Choosing what to target depends on the application. I primarily target "modern" AVX512 microarchitectures because the code runs on servers. ARM64 is much more fragmented and SIMD implementations that are worth the effort are rare. SIMD programming is a wide but shallow domain. You need to memorize a lot of minutiae to be effective but the number of new concepts and idioms you need to grok is relatively limited.
> — [andrewrogers on lobsters · 5 points](https://lobste.rs/s/gkcjic/simd_for_collision#c_dez13l)

> In my experience LLVM is very good at autovectorization. As ~mitchellh writes it’s kind of opaque when autovec will kick in, so it’s difficult to rely on. But when it works it’s hard to beat. [I have done better than LLVM by using features of AVX512 that it didn’t yet know about](https://dotat.at/@/2024-07-28-tolower-avx512.html). But even when the programmer writes explicit SIMD intrinsics, if LLVM knows enough about the intrinsics it will rewrite them in surprisingly clever ways. SIMD intrinsics are not as close to assembly language as I thought! The main difference between my tolower example and ~mitchellh’s example earlier in this thread is that tolower doesn’t have cross-lane dependencies, so it is ideal for the compiler’s optimizations. By contrast ~mitchellh was scanning for an end marker and using that to set up a mask to control which lane computations take effect. However that’s also the similarity between the examples: I did better than LLVM by using AVX512 masked loads and stores to handle the remainder (the “scalar tail”) as masked vector ops instead of as a loop of scalar ops. The impression I got from that work is that autovectorization is great at array processing (which typically works on each lane independently) but not so good at string processing (which has a much greater emphasis on masked ops). Some of this is related to the usual AVX2 target instruction set being weak at masked SIMD and AVX512 being horrifically inconsistent as a target instruction set, and I guess compilers developers will be more motivated to do better SIMD string optimizations if there’s more hardware that can benefit from it. But I’m mostly quibbling that these magical optimizations don’t magically make my code faster, even though they are very close to beating me, and already do speed up a lot of other code. Autovectorization is far better than a research PoC, it’s routinely done by gcc and clang, and you no longer have to pay for intel’s expensive HPC compiler. (Speaking of which, the whole itanium instruction set design was based on the idea that compilers would be able to do static autovectorization better than silicon could do dynamic superscalar dispatch. Oops. [Proebsting’s satirical law](https://proebsting.cs.arizona.edu/law.html) says that compilers take 18 years to make code twice as fast, and _coincidentally_ it was a couple of decades after itanic before autovectorization actually became good.)
> — [fanf on lobsters · 3 points](https://lobste.rs/s/gkcjic/simd_for_collision#c_bmwqya)

> Auto-vectorization is only effective for a narrow minority of use cases. A compiler is not allowed to redesign your data structures and algorithms to be amenable to SIMD because that is part of the code contract. Compilers currently lack the context to understand the code contract. When I worked in HPC decades ago, a compiler capable of effective auto-vectorization was always just a few years away -- it is the fusion power of software. Auto-vectorization is known to be an AI-complete problem which is why so little progress has actually been made over several decades. Current AI is not strong enough to address this but maybe someday.
> — [andrewrogers on lobsters · 2 points](https://lobste.rs/s/gkcjic/simd_for_collision#c_mjupri)

> Auto-vectorization is present in both GCC and LLVM, e.g. https://llvm.org/docs/Vectorizers.html And it is good at finding the simplest cases, which are indeed common! A recent LLVM21 upstream bug broken auto-vectorization for my project and I was able to identify 3 separate areas that I was implicitly relying on auto-vectorization (without realizing it). The result was my benchmarks were 70% slower (almost 2x! from an implicit compiler optimization!). I didn't even realize I was relying on it, so I hand vectorized those code paths and gained it all back. But it really only works for the simplest cases.
> — [mitchellh on lobsters · 4 points](https://lobste.rs/s/gkcjic/simd_for_collision#c_9b72zj)

**Source threads**

- [lobsters](https://lobste.rs/s/gkcjic/simd_for_collision) · 45 points · 11 comments
- [hackernews](https://news.ycombinator.com/item?id=49013464) · 3 points · 0 comments

## Similar posts on daily.dev

- [Inscribed Spheres :: Box2D](https://daily.dev/posts/inscribed-spheres-box2d-dvq55o0po) · 
        
            Box2D 
        
     · 0 upvotes · 0 comments
- [AVX-512: First Impressions on Performance and Programmability](https://daily.dev/posts/avx-512-first-impressions-on-performance-and-programmability-zvccn3onc) · Hacker News · 1 upvotes · 0 comments
- [OpenVDB Introduces SIMD Framework With Some 2~4x Performance Improvements](https://daily.dev/posts/openvdb-introduces-simd-framework-with-some-2-4x-performance-improvements-i70pxiyye) · Phoronix · 0 upvotes · 0 comments

---

[View this post on daily.dev](https://daily.dev/posts/simd-for-collision-box2d-wsosdjqbv)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"SIMD for Collision :: Box2D","url":"https://daily.dev/posts/simd-for-collision-box2d-wsosdjqbv","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/simd-for-collision-box2d-wsosdjqbv"},"datePublished":"2026-07-22T17:58:18.174Z","dateModified":"2026-07-23T07:53:20.780Z","description":"Box3D (the 3D successor to Box2D) applies wide SIMD to the Separating Axis Test (SAT) edge-edge collision phase for complex convex hulls. For a 32-point hull...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/b54a0fb9e17598c57abcd74370c2cdb1?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/b54a0fb9e17598c57abcd74370c2cdb1?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Lobsters","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Lobsters","logo":"https://media.daily.dev/image/upload/s--tl8v_Fku--/f_auto,t_logo/v1698841318/logos/lobste.jpg","url":"https://daily.dev/sources/lobsters"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/simd-for-collision-box2d-wsosdjqbv","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"","timeRequired":"PT6M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Lobsters","item":"https://daily.dev/sources/lobsters"},{"@type":"ListItem","position":3,"name":"SIMD for Collision :: Box2D"}]}
```

