Maybe there are some weird situations where a host that just got its own IP address starts proxying for a third node that wants return packets to asymmetrically bypass the host?
905 karma · joined June 27, 2019
Maybe there are some weird situations where a host that just got its own IP address starts proxying for a third node that wants return packets to asymmetrically bypass the host?
The road to hell is paved with good intentions.
Some recent advances, like the Raspberry Pi Pico's PIO units, have made it possible to do things that MCU's couldn't do before, like emulating a ROM chip. But there are limits to what the PIOs can do.
If it comes to pure computation and not latency, you need some very specific use case before an FPGA becomes better than a regular CPU. Most likely when it involves massive parallelism and custom caches and interconnects. Although nowadays NPUs are starting to fill that niche.
For tiny boards in particular: getting experience and having fun.
Compilers can un-inline as well. In fact, since every function is defined in the header file, the static inline annotation means very little, it's more of a hint; the functions that were not marked static inline can be inlined just as well by the compiler.
One problem with -O3 is that it disregards any effects of the cache (and yes, ESP32s have a bit of cache memory). I recommend using -Os as the default optimization level, as it often has the same or almost the same performance benefits as -O3. Less cache pressure is beneficial, especially for bigger applications, and the smaller code size is of course nice on embedded systems that have limited amounts of flash storage. If you know some specific functions or source files are performance sensitive, you can use pragmas to change optimization for those:
#pragma GCC optimize("O3")
See https://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-.... Clang has a similar pragma, see https://clang.llvm.org/docs/LanguageExtensions.html#extensio....Debian is run by volunteers, and I think Debian Developers would not like it if they would have to pay to work on it, thus there will be some aversion to (at least frontier) LLMs.
That's not the case. First, you can't really extrapolate from endorsers to all of the Debian Developers. Second, endorsers might not have looked at the other proposals at all, and the fact that they only endorsed one option doesn't mean they don't support the others. And you can also endorse an option if you believe it is a valid, useful proposal to add to the GR, even if you don't agree with it personally.
But most importantly, when Debian votes, you don't vote for a single option, instead you rank the choices, and apart from the given options, another option "further discussion" is always added to the list of choices. It's likely that many who rank the most permissive option first will rank the lesser permissive option second, above "further discussion", or they could even give options the same rank (if they really don't think one is better than the other).
A very good way to deal with this is to recognize that all infrastructure needs maintenance and periodic replacement. Once it is time to replace a road, that is when you change it to include bike paths, bus lanes and so on.
You need some foresight, planning, make new road designs part of law, and political will. Some countries have made this work very well.
A PXE boot server has many uses. The project already mentions using it for tools like GParted, Memtest86+ and so on. Booting live OS or OS installers via netboot.xyz is also great. But you can automate things even further; at a previous job (~18 years ago) I used PXE to serve a debian installer image with a preseed file to add user accounts with SSH keys, apt install all the dependencies, and install local binaries to get machines up and running useful stuff without needing to do any manual configuration. Nowadays you'd probably just have it do a minimal install + add just an SSH key, and then let another tool like Ansible take over the rest of the provisioning.
I wrote an encrypted mesh networking library that runs on normal operating systems. A customer asked me if I could make it run on an ESP32 with 520 kiB of RAM. At first this seemed impossible, but it turned out that it was, and not even that hard. While the original library was not memory hungry at all for a desktop CPU, it still wasted space on unnecessarily large buffers. Cutting those out made the library run on an ESP32 while leaving plenty of room for an application.
Also, my first PC was a 200 MHz single-core 32-bit AMD k6 with 32 MiB of RAM. This ran a graphical OS with browsers, word processors, 3D games and so on. Nowadays you can get a CPU with more than that amount of RAM as just built-in cache.
So a good place to start optimizing code would be to actually get a "severely resource constrained" computer and start making your code work on it.
However, thinking about how to make your own setup more robust without having to manually change configuration when one SSL provider stops working is a good exercise. I wonder if you can just get your server's private key signed by multiple SSL providers, and serve multiple certificates to clients, and whether all browsers handle that correctly.
I also tried to use an old phone as a backup device. However, most authentication apps only allow it to be installed on a single device.
I personally think Gerrit works much better than whatever GitHub et al. have for code reviews. As for CI, I would try to keep that out of it as much as possible; just hooks to start a pipeline and to display the result and decide whether to allow a merge or not.
auto [value, text, goose] = std::scan<int, std::string, Goose>(input, "{} {} {}");
A halfway solution would be to have the hypothetical std::scan() take references to std::optional<>s or std::expected<>s: std::optional<int> value;
std::optional<std::string> text;
std::optional<Goose> goose;
/* auto result = */ std::scan(input, "{} {} {}", value, text, goose);
The latter would be type safe, close to how scanf() works, but less satisfying from a functional programming standpoint.Orthogonal to that, adding support for scanning a Goose would be just like how you add a formatter for it, and would be quite similar to a Rust trait. One could imagine having to define something like this:
template<>
struct std::scanner<Goose> {
constexpr auto parse(std::format_parse_context& ctx) {…}
auto scan(std::format_context& ctx) const -> std::optional<Goose> {…}
}; if (sscanf(user_input, "%4u-%2u-%2u", &year, &month, &day) != 3) {
// return an error
}
This still does not catch trailing garbage, but you could check for that as well: if (sscanf(user_input, "%4u-%2u-%2u%c", &year, &month, &day, &dummy) != 3) {
// return an error
}
The result would be 4 if there was at least one trailing character. Too bad there is still no std::scan() companion to C++23's std::print().Things I learned:
- Get an accountant ASAP, even if the income is small. Just the peace of mind that my taxes were being filed correctly was worth the cost.
- You don't need a perfect solution from the start, you are working with your client towards something they can use.
- You need to stay on top of things and communicate regularly, even if your client doesn't.
- Almost all clients wanted me to either come work for them or sell all (rights of) my work to them. This is understandable from their side, but if you want to stay independent you need to set some boundaries.