Closed jiayihu closed 4 years ago
For your information this library does not have a buffer. If you need a 128 byte buffer like you have in Ada, it seems you have to implement it yourself on top of hio::HStdout.
P.S. If you care about speed consider using ITM. It's harder to setup but it's much faster than semihosting.
Okay I was misleaded by these lines, what do they do then?
Anyway semihosting has always been fast enough for my uses, so adding a buffer on top of the lib should be enough. Would you accept a PR?
P.S. If you care about speed consider using ITM. It's harder to setup but it's much faster than semihosting.
For debugging rtt seems more useful.
Okay I was misleaded by these lines, what do they do then?
Output buffering so you can send a whole buffer of bytes instead of having to spoonfed (and error check) each character individually. I don't see too much difference in what the Ada code is doing, maybe the syscall code is faster if you see a huge difference? No idea.
Anyway semihosting has always been fast enough for my uses, so adding a buffer on top of the lib should be enough. Would you accept a PR?
Use of semihosting is kind of discouraged, but If you can come up with trivial optimisation we'd probably take it.
I'd encourage you to check out https://probe.rs and further enhancements like https://github.com/knurling-rs/probe-run for better ways to get debug output.
This lines are an unfortunate consequence of a unix style API for semihosting. When you write a byte array it is theoretically possible the write syscall returns a value that is smaller than the buffer length. In that case we repeat the write until whole array is sent. In practice this never happens so most implementations just ignore the return value like your Ada implementation above.
@therealprof There is no output buffering in this library.
@therealprof Just to make it clear why there is a difference:
When you do
hprintln("Hello {} World!", 5);
it will perform 3 write syscalls "Hello ", "5" and " World!\n".
If each syscall takes 100ms that gives you 300ms in total.
In comparison, the Ada code above will make only 1 write syscall because it buffers the line in a 128 byte buffer. So it will take only 100ms not 300.
In comparison, the Ada code above will make only 1 write syscall because it buffers the line in a 128 byte buffer. So it will take only 100ms not 300.
Well, that's an implementation detail of the formatting code, if you use:
hprintln("Hello 5 World!");
Then it'll be sent at once. If you don't formatting into a separate buffer you can also avoid that.
True, but I think it would be useful to have an extra feature which gives you a buffer by default. Have you seen how many write calls does a simple #[derive(Debug)]
struct do? It's very slow.
128 bytes of RAM is not zero cost either so it has to be an opt-in of course.
@therealprof thanks I've been able to migrate to probe-rs without any issue and it's much easier to use, so I don't have complains on semihosting anymore 😄 I leave closing the issue up to you guys
True, but I think it would be useful to have an extra feature which gives you a buffer by default. Have you seen how many write calls does a simple
#[derive(Debug)]
struct do? It's very slow.
I don't. Nevertheless semihosting has so many drawbacks that it's only remaining application really is to communicate with Qemu for test purposes. Even if we could speed it up by a factor of 10 it would still be very slow and keep all its other disavantages so why even bother, especially at such a cost?
Personally I'm not using semihosting anymore for a very long time. However when I was using it I did make my own buffer so I wouldn't vote against such feature. But if nobody else requires it, this can be closed. Maybe we should put a warning in the docs that this is very old technology and add links to other crates so people can find better options easily.
Closing this, as the question has been answered.
I'm not expert with embedded, but why is semihosting so slow? Single characters appear on the host stdio taking some 100s of ms for each one. I know that semihosting is slow in general, but I hadn't any issue using it from Ada which uses the following implementation:
I know that just pasting the Ada implementation may not be helpful, but unfortunately I'm myself a rookie at both languages and embedded programming (although the code is quite natural to read). I just checked this lib implementation and it already uses a buffer, so I don't what might be the issue. The asm instructions seem also to be the similar although Ada does something more with the registers, but don't trust me.