Settings

Theme

Show HN: SIMD Viterbi Decoder in Rust

github.com

60 points by brian-armstrong 21 hours ago · 10 comments · 1 min read

Reader

I wrote libcorrect in C in 2016 and wanted to revisit it in Rust. Instead of doing just a direct conversion, I went down the rabbit hole of making Rust's std::simd work for me. I ended up with a templated, generic Viterbi decoder for convolutional codes that dispatches the decode at runtime depending on which instruction sets are available. For small rates and orders, the entire decode lives in registers. Larger codes work through memory but take advantage of some acceleration structures.

I also spent some time building a tool to find optimal (max d_free) conv codes for a given rate and order. Of course, there are better mechanisms available today, but I'm happy to talk through anything I learned in the process.

nickcw 10 hours ago

I was looking at the reed Solomon implementation. I've done a few of those in the past! I note that you are using logs for multiplication. I always used to use a 64kb table for direct lookup, though maybe that isn't faster on modern processors?

Next LDPC codes?

eminence32 16 hours ago

Could this library be used decode signals from a GOES satellite downlink? goestools uses libcorrect for this and building a rust version might be fun.

[1] https://github.com/pietern/goestools

  • brian-armstrongOP 15 hours ago

    You could certainly call this crate through a shim in goestools but you'd have to add a Rust dependency. But you could also rewrite goestools in Rust, though it wouldn't be a small undertaking. This crate does have everything you'd need for the forward error correction, at least.

    • femto 11 hours ago

      How do you find the speed of the Rust version of your FEC vs, the C version?

      • johschmitz 9 hours ago

        Performance result are presented here as far as I understand: https://github.com/brian-armstrong/fec#performance

      • brian-armstrongOP 10 hours ago

        I used the benchmarking binaries that ship with libfec. My own crate has a libfec-compatible C shim, so I can link the benchmark against the Rust crate. The benchmark itself reports time spent for a given number of iterations, so the throughput can just be extrapolated from that.

        • femto 10 hours ago

          I got caught out by my Australianism!

          "How do you find the speed of the Rust version of your FEC vs, the C version?"

          translates from "Australian" to "English" as:

          "What is the speed of the Rust version of your FEC vs, the C version?

          Though it was interesting to know how you do it. I'm interested in the speed, as I once looked into using Rust for a signal processing project, but ultimately went with C++ because the team wasn't familiar with Rust. At the time, it seemed to me that Rust had the potential to go faster.

          • brian-armstrongOP 9 hours ago

            Oh! Gotcha! I put a table in the README that lays it all out https://github.com/brian-armstrong/fec#performance

            tldr: My library matches or beats libfec's SSE2 assembly for convolutional codes and pretty steadily beats it in Reed-Solomon. For the convolutional codes, my crate is using a generic, templated decoder rather than hand-written assembly, so it was nice to see that I could match the performance.

ChadNauseam 18 hours ago

I thought this might have something to do with sentencepiece's unigram (which uses viterbi). But they seem to be totally different domains. What an amazing algorithm, to show up in so many different places.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection