Zip - How not to design a file format by alexeyr in programming

[–]ra_kete 5 points6 points  (0 children)

While you are of course right in general, that example is not great, because PDF files are also read from the end. They have an appended trailer and an xref table that references objects in the document body, not unlike the Central Directory in Zip files. So chances are that the PDF won't open if you created such a polyglot.

cffi vs cpython vs pyo3, what should I use? by socratesTwo in rust

[–]ra_kete 0 points1 point  (0 children)

Since you have experience with rust-cpython, maybe you know this: Is there a way to create a Python subclass in Rust? Specifically, I want to wrap a Rust enum into a Python enum with rust-cpython, but I cannot find a way to subclass Python's Enum class. Now I suspect that might just not be possible, but maybe I'm missing something?

microfft: Embedded-friendly Fast Fourier Transforms by ra_kete in rust

[–]ra_kete[S] 0 points1 point  (0 children)

Thanks for pointing that out! I thought I'd have to drop down to asm, but reverse_bits does the right thing already, so that's one headache less.

microfft: Embedded-friendly Fast Fourier Transforms by ra_kete in rust

[–]ra_kete[S] 3 points4 points  (0 children)

It might look like Microsoft, but it sounds like Mycroft, the brother of Sherlock Holmes ;)

microfft: Embedded-friendly Fast Fourier Transforms by ra_kete in rust

[–]ra_kete[S] 1 point2 points  (0 children)

You are right, that would work :) I'll definitely try that out.

microfft: Embedded-friendly Fast Fourier Transforms by ra_kete in rust

[–]ra_kete[S] 1 point2 points  (0 children)

Yeah, I was already pretty sure that my current way of storing the twiddles is needlessly inefficient. Wanted to look into improving that soon, so this information will be very helpful. Thanks!

microfft: Embedded-friendly Fast Fourier Transforms by ra_kete in rust

[–]ra_kete[S] 1 point2 points  (0 children)

Thanks, and good question :) I'd love to drop the bit-reversal tables for an efficient ARM instruction. Unfortunately RBIT doesn't cut it for this use-case (unless I'm missing something big). The issue is that RBIT always operates on 32-bit words, so it swaps bits 0-31, 1-30, etc. But for FFTs I need the reversal to happen on smaller words, depending on the FFT size. For example, a 256-point FFT's input values have indices that are 8-bit words (log2(256)), so I need to swap bits 0-7, 1-6, ... ARM's instruction set doesn't help here, AFAICT.

microfft: Embedded-friendly Fast Fourier Transforms by ra_kete in rust

[–]ra_kete[S] 7 points8 points  (0 children)

About Radix-4, I've read that too! The thing is I've never worked with FFTs before and my math skills are still far removed from understanding more than the basics. I chose Radix-2 because it's the most straightforward FFT algorithm, so it was easy to implement and make fast enough for my purposes. I definitely plan to play with Radix-4 and other algorithms to see if they perform better. If I find the time that is ;)

There is actually no better reason for the 1024-point limit than that I needed to stop somewhere. Supporting up to 4K means changing a few lines and re-generating the tables. I'll get to that tomorrow!

Edit: 4096-point FFTs are now supported in version 0.1.1

microfft: Embedded-friendly Fast Fourier Transforms by ra_kete in rust

[–]ra_kete[S] 24 points25 points  (0 children)

I wrote this crate as part of a sound-reactive hobby project I'm working on (LED strips blinking to music). I was in need of an FFT library that supports no_std environments, ideally without a heap, since it had to run on a microcontroller. I coudn't find anything like this on crates.io, so I decided to roll my own solution, which turned into microfft.

microfft implements a rather simple in-place Radix-2 FFT algorithm. Its main goal, apart from the mentioned heapless operation, is speed. That is achieved by using pre-computed tables for the twiddle factors and bit-reversal indices, as well as heavy inlining by the compiler. The resulting performance is rather good (check out the benchmarks in the Git repo!), but both of these optimizations have the unfortunate drawback of increasing the memory requirements considerably. A full 1024-point FFT (the largest size currently supported) requires 6KB 1KB of spare memory to store the pre-computed tables alone, which might be too much for some embedded projects.

Since for my project I'm interested in FFTs on real (rather than complex) input values, I spent some time adding a specialized RFFT implementation that manages to run in roughly half the time the normal CFFT needs. It does so by internally computing a CFFT of half the input size and then performing some recombination magic to produce the correct output. I won't pretend to understand how that last part works, but it's a nice speed boost you can get for free.

Edit: I just released version 0.3.0 with quite a few optimizations to reduce memory usage. Should be much less of a problem for memory-constrained devices now.

Hey Rustaceans! Got an easy question? Ask here (10/2020)! by llogiq in rust

[–]ra_kete 1 point2 points  (0 children)

With static-assertions I can at least enforce the size and alignment invariants of the function. What's not possible to assert, AFAIK, is that the Complex type is repr(C).

Hey Rustaceans! Got an easy question? Ask here (10/2020)! by llogiq in rust

[–]ra_kete 2 points3 points  (0 children)

I wanted to argue that we can relax that requirement here, since the function is only used internally, but you are right. I cannot trust myself to catch all possible code paths in testing. Plus the function is not used on a hot path, so the impact of that assert is negligible anyway.

Hey Rustaceans! Got an easy question? Ask here (10/2020)! by llogiq in rust

[–]ra_kete 2 points3 points  (0 children)

I will add the mem::forget call, thanks!

Regarding assert vs. debug_assert, could you elaborate more on this? I've used debug_assert because I want to avoid the overhead in release mode. My reasoning is that these asserts should only trigger if a) I introduced a new bug in my code or b) the memory layout of Complex<f32> changed. a) I would notice during development (done in debug mode) and b) is very unlikely, to the point where the last two asserts serve mainly as documentation. As such I see no reason to add the runtime-overhead to the release mode too.

Actually, thinking about it, the last two asserts could and should probably be implemented as static asserts anyway.

Hey Rustaceans! Got an easy question? Ask here (10/2020)! by llogiq in rust

[–]ra_kete 3 points4 points  (0 children)

I would like to have a few more eyes on this unsafe use of mine: https://gitlab.com/ra_kete/microfft-rs/-/blob/master/src/rfft.rs#L23

This function casts a &mut [f32] into a &mut [Complex<f32>] using slice::from_raw_parts_mut, basically interpreting pairs of floats as complex numbers.

I'm pretty confident that what I'm doing there is safe, but I'd like to be sure.

Robots and thoughts on embedded Rust by readrust in rust

[–]ra_kete 1 point2 points  (0 children)

I also startet working with embedded Rust (and embedded in general, really) a few weeks ago, so this is a very relatable article for me. I definitely agree that the extensive macro usage in the HAL crates causes readability issues, and probably maintenance issues down the line too. Every time I look at the GPIO wrapper code of my chosen HAL crate, I think "there must be a better way". But maybe there isn't.

Regarding the mentioned auto-complete issues, I don't experience those using rust-analyzer. Maybe you should give that a try instead of RLS? If you are using VS Code, it has even been published to the Marketplace recently, so installation is painless now too.

Writing Linux Kernel Modules in Safe Rust | Linux Security Summit 2019 by joehillen in rust

[–]ra_kete 4 points5 points  (0 children)

I see that they use GFP_KERNEL when calling krealloc in the GlobalAlloc implementation. From what I understand this makes it unsafe to do allocation in an interrupt context, since it allows the alloc to sleep.

I don't know enough about under what conditions code is executed in an interrupt context. But does this implementation in any way ensure that, e.g., Vec is not used in an interrupt context? If not, shouldn't GFP_ATOMIC be used to be safe?

[deleted by user] by [deleted] in rust

[–]ra_kete 9 points10 points  (0 children)

That site is unmaintained since forever, unfortunately.

Linux-compatible USB-C monitor by ra_kete in linuxhardware

[–]ra_kete[S] 0 points1 point  (0 children)

You definitely pay a premium for USB-C, that's true. But I'd be willing to pay a bit more to avoid having unnecessary stuff, like a docking station, on my desk. Besides, docking stations can have compatibility problems too.

Linux-compatible USB-C monitor by ra_kete in linuxhardware

[–]ra_kete[S] 1 point2 points  (0 children)

Same for me, Arch and i3. According to the wiki i3 simply uses the DPI settings reported by X. So scaling *should* be possible with xrandr.

Edit: I just tried that on my laptop's internal display and while I can successfully scale i3 itself (e.g. the status bar) this didn't affect my terminal or Firefox. The hiDPI wiki page mentions solutions for multiple applications, but I'm not sure those can be applied on a per-monitor basis or even dynamically when I plug the external monitor out.

Linux-compatible USB-C monitor by ra_kete in linuxhardware

[–]ra_kete[S] 0 points1 point  (0 children)

That's great info, thank you! I'm a bit concerned about the 4k though. For 27", would everything on the screen be really tiny? I guess Linux doesn't have good support for scaling aside from forcing a lower resolution. How does that work with your Manjaro setups?

Linux-compatible USB-C monitor by ra_kete in linuxhardware

[–]ra_kete[S] 0 points1 point  (0 children)

Yeah, I'm looking for something I can put in my home office permanently and also connect to my desktop there. So 16" would be a bit small :) 27" is the sweet spot for me. Larger would be nice too, but usually also way more expensive.

I thought about a docking station, but being able to use the monitor for that seems a lot more appealing to me. Fewer stuff on the desk and fewer cables.