ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to #rust-embedded:matrix.org and logged at https://libera.irclog.whitequark.org/rust-embedded, code of conduct at https://www.rust-lang.org/conduct.html
IlPalazzo-ojiisa has quit [Quit: Leaving.]
starblue has quit [Ping timeout: 248 seconds]
starblue has joined #rust-embedded
<re_irc> <@jamesmunns:beeper.com> Was looking at some code that did a lot of fixed point math recently, opt level s was half the size of opt level 3, with opt level z in the middle. But for my benchmarked code, opt level 3 was 40ms, opt level s was 50ms, and opt level z was 80ms
starblue has quit [Ping timeout: 252 seconds]
starblue has joined #rust-embedded
<re_irc> <@therealprof:matrix.org> Yeah, with multiscalar pipelined CPUs with tons of cache all over the place compiler heuristics tend to make weird assumptions about the straight forward low end.
<re_irc> <@jamesmunns:beeper.com> (this was on an nrf52), but yeah turning on I cache brought the numbers down to like 35/40/55
starblue has quit [Ping timeout: 240 seconds]
starblue has joined #rust-embedded
IlPalazzo-ojiisa has joined #rust-embedded
emerent has quit [Ping timeout: 256 seconds]
emerent has joined #rust-embedded
Dr_Who has joined #rust-embedded
<re_irc> <@boiethios:matrix.org> Hey, are you aware of any stack-based vector than can be built at compile-time? I had a look at arrayvec and heapless::Vec, but none of them allows that.
<re_irc> <@bumblebee10:matrix.org> but what would a stack based vector be? there are non-dynamic fixed-size arrays, [0u8; usize], but i guess that's not what you want?
<re_irc> <@boiethios:matrix.org> bumblebee10: That's a vector whose items are on the stack, like arrayvec or heapless::Vec.
<re_irc> <@boiethios:matrix.org> Those are no-std friendly vectors.
<re_irc> <@jamesmunns:beeper.com> I guess the more enlightening question is "what are you trying to achieve"?
<re_irc> <@jamesmunns:beeper.com> Like, a static initialization value?
<re_irc> <@boiethios:matrix.org> It's a bit long to explain…
<re_irc> <@jamesmunns:beeper.com> like a vector that COULD hold 32 items, but starts with 8 specific items always?
<re_irc> <@boiethios:matrix.org> : Basically, yes
<re_irc> <@jamesmunns:beeper.com> or a read only, constant item?
<re_irc> <@boiethios:matrix.org> : Read only, constant. I need a vector, because it's a field inside a struct, something like "Foo<const N: usize> { bar: &'static[Bar] }" and I need an array of those "foo"s. I don't want the vector to be inline, because that would use a huge amount of bytes, while with this, it only cost a reference when needed.
<re_irc> <@boiethios:matrix.org> * "Foo { bar: &'static [Bar]
<re_irc> <@boiethios:matrix.org> So, the aim is: the user passes a const slice in, and I build a const stack-based vector whom I pass as a slice to build this struct.
<re_irc> <@jamesmunns:beeper.com> okay, so why not:
<re_irc> const ITEMS: &[Ex] = &[
<re_irc> And then just use
<re_irc> Foo {
<re_irc> Ex::new(),
<re_irc> ];
<re_irc> // ...
<re_irc> bar: &'static [Ex],
<re_irc> }
<re_irc> impl Foo {
<re_irc> const fn new() -> Self {
<re_irc> Foo { bar: ITEMS }
<re_irc> }
<re_irc> }
<re_irc> <@jamesmunns:beeper.com> or
<re_irc> fn from_slice(s: &'static [Ex]) -> Self {
<re_irc> impl Foo {
<re_irc> }
<re_irc> Foo { bar: s }
<re_irc> }
<re_irc> <@boiethios:matrix.org> I need to normalize the content passed in, which can be done at compile-time
<re_irc> <@jamesmunns:beeper.com> uhh, you'd probably need to do that in two steps, mutating a const isn't really a thing
<re_irc> <@jamesmunns:beeper.com> usually you "check and panic if not right"
<re_irc> <@boiethios:matrix.org> I don't want to mutate the input, I'll create a new array/vector from the input.
<re_irc> <@boiethios:matrix.org> I need to loop over the input, then push what I need to into the output.
<re_irc> <@jamesmunns:beeper.com> Yeah, so const isn't that comprehensive yet, really.
<re_irc> <@jamesmunns:beeper.com> you can sort of approximate that today, but you'd need to specify exact sizes of arrays in most cases
<re_irc> <@jamesmunns:beeper.com> there's no real "leak vec to const" capability today.
<re_irc> <@jamesmunns:beeper.com> you could do something like
<re_irc> const INPUT: &[Ex; T] = ...;
<re_irc> const fn normalize<const N: usize>(&'static [Ex; N]) -> [ExNormalized; N] {
<re_irc> // ...
<re_irc> }
<re_irc> const DATA: [Ex; 23] = ...;
<re_irc> const YAY: Foo = Foo::from_norm(&DATA);
<re_irc> <@jamesmunns:beeper.com> or something
<re_irc> <@jamesmunns:beeper.com> err
<re_irc> const DATA: [ExNormalized; 23] = ...;
<re_irc> <@boiethios:matrix.org> Hum, I see. My code looks like that:
<re_irc> where
<re_irc> I: LayerIndex,
<re_irc> pub enum Action<I>
<re_irc> {
<re_irc> KeyPress(KeyPress),
<re_irc> /// A regular key press: optional weak modifiers and one key.
<re_irc> // /// Several key presses.
<re_irc> // Combo(todo)
<re_irc> /// A regular (strong) modifier press.
<re_irc> Modifiers(Modifiers),
<re_irc> /// Change the layer as long as the key is pressed.
<re_irc> LayerChange(LayerChange<I>),
<re_irc> /// Handle a tap and a hold differently.
<re_irc> TapOrHold(TapOrHold<I>),
<re_irc> /// A macro, returning several keys.
<re_irc> Combo(Combo),
<re_irc> /// Custom action
<re_irc> Custom(Custom<I>),
<re_irc> }
<re_irc> This enum weight 24 bytes. Combo can have a great amount of bytes of information, and if I store it inline, it can multiply the size of the enum by 10, which may not be sustainable (or so I think)
<re_irc> <@boiethios:matrix.org> Hum, I see. My code looks like that:
<re_irc> pub enum Action<I>
<re_irc> where
<re_irc> I: LayerIndex,
<re_irc> {
<re_irc> /// A regular key press: optional weak modifiers and one key.
<re_irc> KeyPress(KeyPress),
<re_irc> /// A regular (strong) modifier press.
<re_irc> Modifiers(Modifiers),
<re_irc> /// Change the layer as long as the key is pressed.
<re_irc> LayerChange(LayerChange<I>),
<re_irc> /// Handle a tap and a hold differently.
<re_irc> TapOrHold(TapOrHold<I>),
<re_irc> /// A macro, returning several keys.
<re_irc> Combo(Combo),
<re_irc> /// Custom action
<re_irc> Custom(Custom<I>),
<re_irc> }
<re_irc> This enum weight 24 bytes. Combo can have a great amount of bytes of information, and if I store it inline, it can multiply the size of the enum by 10, which may not be sustainable (or so I think)
<re_irc> <@boiethios:matrix.org> * weights
<re_irc> <@boiethios:matrix.org> This is what I'm trying and fix.
<re_irc> <@boiethios:matrix.org> : The normalized data can take more space or less, depending on the input.
<re_irc> <@jamesmunns:beeper.com> So, the usual answer to this manually would be to have Combos take a "&'static [KeyPress]" (or whatever). This means tho you sorta have to write out all the items you want
<re_irc> <@jamesmunns:beeper.com> the not-manual answer to this is "macros"
<re_irc> <@boiethios:matrix.org> I don't want to use macros.
<re_irc> <@jamesmunns:beeper.com> const can't really do "N items in, M items out, where N AND M are not specified"
<re_irc> <@jamesmunns:beeper.com> the other option is "generate some code in a build rs, from like a JSON or YAML file"
<re_irc> <@boiethios:matrix.org> OK, thanks for the help. I'll think about all of that.
<re_irc> <@jamesmunns:beeper.com> There is some "far future" talk about being able to allocate a Vec in a const fn at compile time, and decay to a const slice or array, but I don't think that's possible even w/ unstable features today
<re_irc> <@jamesmunns:beeper.com> (there's a lot of "it breaks a ton of assumptions everywhere" issues with it, I don't have the issue at hand tho)
<re_irc> <@boiethios:matrix.org> : Well, it's no-std, so I cannot use a "Vec" anyway, nor allocate, more generally.
<re_irc> <@jamesmunns:beeper.com> yeah, the idea is you use a Vec _at compile time_, and it becomes a slice/array you can use
<re_irc> <@jamesmunns:beeper.com> so at COMPILE TIME you use an allocator, but it is not needed at runtime
<re_irc> <@boiethios:matrix.org> Oh, I see.
<re_irc> I could ask the user to provide a "&'static mut [u8]" which would be used as a poor man's allocator.
<re_irc> <@jamesmunns:beeper.com> not exactly? but also I'm describing a feature that doesn't exist, so feel free to ignore
<re_irc> <@jamesmunns:beeper.com> the goal would be to allow something like:
<re_irc> const fn example(x: &'static [Key]) -> &'static [Combo] {
<re_irc> for k in x {
<re_irc> if k.valid() { v.push(k.into()); }
<re_irc> let mut v = Vec::new();
<re_irc> }
<re_irc> v.as_slice()
<re_irc> }
<re_irc> <@jamesmunns:beeper.com> or something
<re_irc> <@boiethios:matrix.org> Exactly
<re_irc> <@jamesmunns:beeper.com> or return a Vec that can be used without an allocator (maybe only in a read only way), this sorta talks about it: https://github.com/rust-lang/const-eval/issues/20
<re_irc> <@jamesmunns:beeper.com> but yeah. Rust super can't do that at all today.
<re_irc> <@boiethios:matrix.org> Maybe I could write something like:
<re_irc> const fn example(x: &'static [Key], buffer: &'static mut [Combo]) -> &'static [Combo] {
<re_irc> }
<re_irc> // etc.
<re_irc> <@jamesmunns:beeper.com> the issue is "how big is the array you return"
<re_irc> <@boiethios:matrix.org> I could compute the size upfront with another function. I would do twice the job, but it's at compile-time
<re_irc> <@jamesmunns:beeper.com> there might be a tricky way to do it and wrap it up in a lib! But I am not aware of it
<re_irc> <@jamesmunns:beeper.com> Also I don't think you can do "&'static mut [Combo]"
<re_irc> <@jamesmunns:beeper.com> (in const-fn)
<re_irc> <@jamesmunns:beeper.com> okay
<re_irc> <@jamesmunns:beeper.com> so I don't RECOMMEND this
<re_irc> <@jamesmunns:beeper.com> You _can_ get const to do fancy things sometimes, but you miiiight want to wrap it into a macro that does this stuff under the hood.
<re_irc> <@jamesmunns:beeper.com> (if you want to end up with basically "&[&[Key]]" tho, it gets way more complicated)
<re_irc> <@boiethios:matrix.org> : I don't. The final result will be a slice of HID reports.
<re_irc> <@boiethios:matrix.org> IIUC correctly your example, without a macro, the user has to find the correct "N" by trial and error?
<re_irc> <@boiethios:matrix.org> Oh, no, I see
<re_irc> <@jamesmunns:beeper.com> or needs to invoke all the steps themselves, e.g.
<re_irc> // ...
<re_irc> const INPUT: &'static [Key] = &[
<re_irc> const COMBOS: &'static [Combo] = &example::<GOOD_CT>(INPUT);
<re_irc> const GOOD_CT: usize = how_many_good(INPUT);
<re_irc> ];
<re_irc> <@jamesmunns:beeper.com> vs you could hide those three calls in a macro that takes (what will be used to initialize) "INPUT".
<re_irc> <@boiethios:matrix.org> In fact, I'm talking about "const", but what I really want is a static slice.
<re_irc> <@jamesmunns:beeper.com> Yeah, you want to generate a static slice using a const-fn
<re_irc> <@jamesmunns:beeper.com> so that all the thinking is done at compile time, and at run time, you are left with only (references to) data
<re_irc> <@boiethios:matrix.org> Maybe there is an alternate way of having a static slice, without a const fn.
<re_irc> <@jamesmunns:beeper.com> - you type it out
<re_irc> - you make a macro that types it out
<re_irc> - you make a build rs that types it out
lehmrob has joined #rust-embedded
sauce has quit []
IlPalazzo-ojiisa has quit [Quit: Leaving.]