That's a huge help. I only need about 20 threads in Rust, some of which are compute-bound. So involving "async" is totally the wrong tool for the job. Goodbye, Tokio.
> So involving "async" is totally the wrong tool for the job. Sadly with so many things having gone async-first (or only) it’s become difficult not to end up with an async runtime anyway, or not be forced to use an async system. I wanted to build a small web-based tool for local, didn’t really find anything which was not async.
Comparison of Rust async and Linux thread context switch time and memory use
121–130 of 201 posts
Re: Comparison of Rust async and Linux thread context switch time and memory use
#122Performance profiling on a laptop is largely pointless. There's too much stuff trying to conserve power by limiting performance.
Re: Comparison of Rust async and Linux thread context switch time and memory use
#123The problem with threads is you need to correctly size your thread pool. That's hugely difficult if you have unknown lengths of blocking IO.
Re: Comparison of Rust async and Linux thread context switch time and memory use
#124Earlier quoted context omitted.
Ease of understanding multithreaded code and wait on results or perform standard control flow constructs in a multithreaded environment? This is a great example in Node on useful combinators that with async await make it easy to express parallel programming concepts with familiar tools. No manual IPC, no fork/join child PID/thread ID handling, etc. https://github.com/sindresorhus/promise-fun The same abstractions (or…
> Ease of understanding multithreaded code Rust is not Javascript. Using threads is actually a lot simpler in Rust than async/await.
Re: Comparison of Rust async and Linux thread context switch time and memory use
#125Performance profiling on a laptop is largely pointless. There's too much stuff trying to conserve power by limiting performance.
Are your users going to be running your application on laptops? Will they have the same "conserve power by limiting performance" going on? If so, that is _exactly_ the environment you want to do performance work in, generally speaking.
Re: Comparison of Rust async and Linux thread context switch time and memory use
#126> People often see that there's some theoretical benefit of async and then they accept far less ergonomic coding styles and the additional bug classes that only happen on async due to accidental blocking etc... despite the fact that when you consider a real-world deployed application, those "benefits" become indistinguishable from noise. However, due to the additional bug classes and worse ergonomics, there is now le…
It seems to me that these are two orthogonal topics. One thing is how you represent tasks, either using OS threads or async tasks. And the other is how you structure concurrency. Maybe I'm missing something, but I think there is nothing preventing the use of those structured concurrency patterns using OS threads as the base for tasks. Then you get some nice benefits of doing this such as proper stack-traces and easie…
Re: Comparison of Rust async and Linux thread context switch time and memory use
#127Earlier quoted context omitted.
Keep in mind that a new async task doesn't create a new thread. So yes, "not creating a new thread" is 3x faster than "creating a thread". If the app layer can context switch using language level constructs, and do co-operative switching, then yes, one gets the 3x benefit. imho, whether the async executor and scheduler is performant enough to manage the tasks is what one should worry about.
I'm confused. If many async tasks are ran on a single thread, what the thread does when is blocked waiting for things to happen? Does it sleep? If so, a context switch takes place anyway. If not, what is the impact on GUI applications? If I have a main thread to manage my GUI, should I spin a new thread to run my async tasks? A modern microcontroller/microprocessor is inherently event driven (for example, on ARM, at…
for network io, behind the scenes this is most likely utilizing epoll system calls. epoll mitigates context switch problem in a few ways, mostly because there is only one stack context to notify about new io events, instead of many.
Re: Comparison of Rust async and Linux thread context switch time and memory use
#128> People often see that there's some theoretical benefit of async and then they accept far less ergonomic coding styles and the additional bug classes that only happen on async due to accidental blocking etc... despite the fact that when you consider a real-world deployed application, those "benefits" become indistinguishable from noise. However, due to the additional bug classes and worse ergonomics, there is now le…
That's interesting to hear - but how much of an investment is it to climb the that mountain (or hill) that makes you comfortable with working with the async model?
Re: Comparison of Rust async and Linux thread context switch time and memory use
#129Earlier quoted context omitted.
In Javascript, this is a typical rookie mistake. Every newcomer would do it once, get lectured about `Promise.all` in code review, and move on. Honestly, I'd be really surprised if this was a common practice in C#.
Rust doesn’t allow you to do this.
Re: Comparison of Rust async and Linux thread context switch time and memory use
#130Earlier quoted context omitted.
Speaking of futures_unordered and similar patterns, I think a part of the "async promise" that has failed is the lack of concurrency for a single user request by default in most languages. That is, the 'easy' path is to write code such as the following (in vaguely C# pseudocode): var p = await GetUserPermission( username ); var c = await GetServerConfig(); var m = await GetMessageOfTheDay(); Assume each await call is…
I've been using C# for around 20 years, basically since it was first released. I never personally had any issue with working with threads and locks, finding it simple enough to reason about them, though I understand lots of people felt differently. When async/await first came to C# around 10 years ago, I grumbled because I didn't see the point; I found it much harder to reason about the flow of code, and initially at…
But most of the time you not only use thread, but also several synchronization primitives (locks, channel, etc.) and when doing so, regarding stack trace you are in an even worst situation than what async stack traces gives you (“some thread changed this shared-memory value and now it's not what you expected, but you have no easy way to know which one did and when, good luck”).