What Irregularity Costs: CUDA C++, Rust, and Triton on a Hash-Blocked GPU Workload
This paper demonstrates that while CUDA C++, Rust, and Triton perform similarly on regular GPU workloads, their efficiency diverges drastically on irregular hash-blocked tasks due to language-specific limitations in expressing atomic operations and loop bounds, with Rust suffering from cache coherence issues and Triton from unmaskable atomics and compile-time loop constraints.
Original paper licensed under CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/). This is an AI-generated explanation of the paper below. It is not written or endorsed by the authors. For technical accuracy, refer to the original paper. Read full disclaimer
The Stage and the Players
Imagine you are trying to build a 3D model of a room using a camera that takes thousands of pictures. To make this happen, your computer needs to organize a massive amount of data about every tiny piece of space in that room. This is the world of GPU programming, where "GPUs" are the super-fast graphics chips inside computers that are also brilliant at doing millions of math calculations at once.
Usually, when people compare different programming languages for these chips, they test them on very neat, predictable tasks, like multiplying giant grids of numbers. It's like testing a race car on a perfectly straight, empty highway. Every lane is the same, and every driver knows exactly how long the race will take. But the real world is messy. In applications like virtual reality or robot navigation, the computer has to deal with chaotic, unpredictable data. It's like sending that same race car into a crowded, winding city street where traffic jams happen randomly, and drivers have to stop and start constantly. This paper asks a simple but crucial question: When the road gets messy, do all the programming languages perform the same, or do some get stuck in traffic while others zoom through?
The Great GPU Language Showdown
In this study, researchers took three popular ways to talk to these super-chips—CUDA C++ (the old-school, hand-written standard), Rust (a modern language known for safety), and Triton (a newer tool designed to make coding easier)—and put them to work on a very specific, chaotic job: building a 3D map of a room using a "hash table."
Think of a hash table like a giant, chaotic locker room. You have thousands of people (data points) trying to find a locker (a spot in memory) to store their stuff. Sometimes the locker they want is empty, so they take it. But often, the locker is already taken, so they have to check the next one, and the next one, until they find an open spot. In a perfect world, everyone finds a locker instantly. In this "irregular" workload, some people find lockers immediately, while others have to search for a long time, and everyone is fighting over the same few lockers at the same time.
The researchers ran the same exact job on all three languages and measured how fast they finished. The results were a shock: The languages behaved completely differently depending on the type of work.
The "Regular" Part: A Dead Heat
First, they tested the "regular" part of the job, which is like walking down a hallway and painting every wall you see. This part is predictable. On this task, all three languages were almost identical. Whether you used the old-school CUDA, the modern Rust, or the easy-to-use Triton, they finished in roughly the same amount of time. If you only looked at these neat, predictable tests (which is what most other studies do), you would think it doesn't matter which language you pick.
The "Irregular" Part: The Great Split
Then, they tested the "irregular" part: the chaotic locker room search. This is where the story changes dramatically.
- Rust vs. CUDA C++: The Rust language performed almost exactly as well as the hand-written CUDA C++. It was just a tiny bit slower (about 1% to 3% in some cases), which is practically a tie. Rust proved it could handle the messy, unpredictable traffic just as well as the veteran.
- Triton's Struggle: Triton, however, hit a massive wall. On the chaotic search task, it was more than 10 times slower than the other two. In some real-world tests with actual room scans, it was nearly 30 times slower.
Why Did Triton Get Stuck?
The researchers didn't just say "Triton is slow"; they figured out exactly why it was stuck, and it wasn't because the code was written poorly. It was because of how the language is built.
Imagine Triton is a strict teacher who insists that every student in a class must stay in their seat for a fixed amount of time, even if they finish their work early. In the chaotic locker room, some threads (students) find a locker in one second, while others take ten seconds.
- The Problem: Triton forces the fast threads to wait in a loop until the slowest thread finishes, even though they have nothing left to do. It's like a race where the winner has to stand still and wait for the last person to cross the finish line before anyone can leave the track.
- The "Mask" Issue: Furthermore, Triton lacks a specific tool (called a "mask") that lets the fast threads stop working entirely. Instead, they have to keep running a dummy task, wasting energy and clogging the system. The researchers found that this design choice forced the computer to do a massive amount of useless work, slowing everything down by a factor of 10 to 30.
- A Hidden Danger: There was also a safety issue. Because Triton forces a fixed time limit on the search, if the locker room gets too crowded, the search might give up and stop looking. This means the computer silently throws away parts of the 3D room, creating invisible holes in the final model. The researchers found that at certain crowd levels, Triton would lose entire chunks of the surface, while the other languages found them perfectly.
Why Rust Was a Little Slower (The Invisible Trap)
Rust was very close to winning, but it wasn't quite as fast as the hand-written CUDA code. The researchers spent a long time trying to find out why, checking the number of instructions and the memory used. They found that Rust was actually doing less work than CUDA, yet it was still slower.
The culprit was a hidden trap in how Rust handles safety. Rust has a feature that makes reading shared data "safe" by ensuring everyone sees the same version. However, on these specific chips, the "safe" way to read data forces the computer to skip its fastest memory cache and go to a slower one. It's like a security guard who insists on checking every single package at the front door, even though the packages are already known to be safe. This extra step slowed Rust down by about 20-30%, but it was a tiny price to pay compared to Triton's massive slowdown.
The Takeaway
The main lesson of this paper is that you cannot judge a programming language just by how it performs on neat, predictable tasks.
If you only test on the "regular" highway, Rust, CUDA, and Triton all look like champions. But once you throw them into the "irregular" city traffic of real-world 3D mapping, the results split wide open.
- Rust is a strong contender, staying nearly as fast as the best hand-written code.
- Triton, while great for neat tasks, struggles mightily with chaotic, unpredictable work, becoming dozens of times slower and potentially losing data without anyone noticing.
The researchers conclude that for tasks involving messy, real-world data, choosing the wrong language isn't just a small inconvenience; it can make your program unusably slow or cause it to fail silently. They also found that many previous studies missed this because they only tested the "regular" parts, leaving the dangerous, messy parts unexplored.
Drowning in papers in your field?
Get daily digests of the most novel papers matching your research keywords — with technical summaries, in your language.