Release note highlights #

  • New map implementation is that high performance, cache-friendly, and uses a open-addressed Robin Hood hash map data structure with various optimizations for Odin
    • Uses a smaller data structure than previously (4 pointers, down from 7)
    • SOA-based memory layout
    • Up to 4x-6x faster insertion and lookup on average
    • Entries are store in non-contiguous cell-layout which means no element straddles across a cache line
    • Only one allocation per map instead of two (previously hashes and entries)
    • Allows for calling delete_key whilst iterating across the map
  • And much more!

Interview with Cloin, author of spall #

Q: Let’s start at the beginning. How did you find out about Odin and what appealed to you about it?

A: It’s been so long since I first heard about Odin, I’m not sure my memory is entirely accurate, but I remember Bill plonking around with it ~5-6 years ago, as a fun little project. I use a lot of C for little tools and libraries, because I often wind up having to write performance-critical parsers for wonky binary formats. Odin is a huge sigh of relief for some of C’s major pain points, with handy built-in data structures, endian types, and pleasant enum printing.

For prototyping, having hashmaps, dynamic arrays, and generics on hand is a major timesaver, for binary format parsers, endian-types are a big clarity win, I can define the format as-is, rather than manually swapping endianness after parsing, and for debugging, tests, and error handling, enum printing saves me mountains of xmacro-wrapped enums and printer-helpers.

Q: And now you’re using it to develop a very impressive piece of kit. Can you tell us something about what prompted you to write spall, and why Odin was the right fit?

A: Spall was written on a whim. Ben Visness of Handmade Network fame asked around for a replacement for the soon-to-be-deprecated chrome://tracing, and I thought it sounded like a fun little project to tackle. chrome://tracing is a browser-based profiler, so I had to play on its terms (at least to start). I chose Odin because it had reasonable WASM support, and was relatively painless to get up and running (after knocking out a few little issues here or there). Odin’s custom allocator support turned out to be a critical feature, making spall fast and lightweight with WASM’s low-memory footprint, high allocation-cost constraints.

Q: You’ve run into some problems with WASM as a target, namely memory limits and file I/O. Is there something Odin can do here, or are these inherent platform-specific issues?

A: Sure! WASM does have some frustrating constraints, and Odin definitely isn’t perfect.

There’s a decent chunk of things that are fixable!

Odin doesn’t yet provide a default allocator for WASM, so you have to write your own on top of the wasm page-alloc intrinsic, which is a bit of a painful newbie-hurdle.

Odin doesn’t enable the LLVM -bulk-memory target flag by default, so memcpy and memmove, which Odin uses heavily to do 0-initialization of memory/structs (a lovely feature), end up quite expensive unless you know to enable the flag.

wasm32 (the stable one) is 32-bit platform in a 64-bit world. Odin uses signed integers that are pointer-width (32-bit on wasm32) for slice indexing to try to help users catch underflow errors. Unfortunately, WASM, unlike many 32-bit platforms, gives you access to all 4 GB of the address space, which means that you have to deliberately disable bounds-checking and replace parts of core:mem in order to work with the full address space, and it still doesn’t quite work.

And, of course a lot of things that Odin can’t really fix, mostly related to memory.

Odin’s new map is amazing for native code, but on platforms like WASM where you don’t have the ability to free memory back to the OS, it is a major source of fragmentation.

Odin’s datastructures can’t handle getting close to the memory cap well. When dealing with dynamic arrays on a system like WASM with a hard memory cap and no virtual address space, you can quickly run out of space when they grow and double beyond your available space. Unfortunately, WASM doesn’t make that one easy to correct for, there’s no good way to know how much memory you can use ahead of time, so you can just run out of memory without warning and be up the creek without a paddle.

Hopefully WASM’s memory model will get a little more sane in the coming years.

Q: What would you say your favorite thing about Odin is, and what would you say could be improved? This could be a feature, syntax, the community, documentation, tooling, anything and everything related to working with Odin that you really like and think could use some love, respectively, and why?

A: My favorite thing about Odin is multiple return for functions! Coming from the C space, I love that I can finally make error handling consistent across functions. No more checking for return signedness/zero-ness, or a random passed-in pointer. I just pass the error back and move on.

The biggest Odin pain point in my mind is documentation, for sure. There’s so much in the language that still needs a little more explanatory love. There are a few hidden pitfalls with things like the current temp allocator, bit_sets, and a bunch of features like cap() for dynamic arrays that only get mentioned in passing that could use a little more attention. It’s an active work-in-progress, I’m confident it will get better as we go along.

Q: Back to spall, how is the desktop version coming along and where can we learn more about this exciting new tool?

A: I’ve made decent headway on the desktop version! I’ve currently got it running on OSX, Windows, and Linux, Odin made it pretty trivial to port all of the crunchy application code.

I’ve got it working almost as well as the web-version, it runs about ~2-3x faster, and it allows you to allocate with as much memory as you have, which is a huge upgrade. I’m deep in platform-layer code at this point. SDL doesn’t do smooth window resizing, file open dialogs, or smooth-scrolling well, so I’ve got a pile of work to do, polishing the rough edges and making it feel like a well-made native app everywhere you might want to use it.

If you’ve got a project you want to profile and want to get started with the web version of spall, it’s free and available on https://gravitymoth.com/spall. The web version is MIT-licensed, and available on https://github.com/colrdavidson/spall if you want to read the code or grab the single-file C header library and integrate it into your system.

Hopefully I’ll have a release of the native version up for sale on itch.io in the next month or two for those who need to profile big projects or want a few more little convenience features.

Q: Was there anything you wanted to say about Odin or spall in addition to this? Any sage advice to newcomers to the language?

A: The community is very responsive, and happy to answer questions if you run into issues! I highly encourage newbies to check out the discord, and ask questions when they run into problems with the language. It helps us a ton, figuring out where the documentation needs the most work, and if it gets you unstuck and on the road to a happy Odin user, it’s a major win-win.