Live data from Hacker News

Maybe Rust isn’t a good tool for massively concurrent, userspace software

bitbashing.io

491–500 of 624 posts

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#491
post #352

Earlier quoted context omitted.

> Said another way, explain how you solved the problems of just synchronously waiting for async. Why? It isn't solved for async functions, is it? Just because the async is propagated up the call-stack doesn't mean that the call can't deadlock, does it? Deadlocks aren't solved for a purely synchronous callstack either - A grabbing a resource, then calling B which calls C which calls A ... Deadlocks are potentially the…

Yes actually it is solved. If you stick to async then it cannot deadlock (in this way) because you yield execution to await.

> Yes actually it is solved. If you stick to async then it cannot deadlock (in this way) because you yield execution to await.

Maybe I'm misunderstanding what you are saying. I use the word "_implementation_type_" below to mean "either implemented as option 1 or option 2 from my post above."

With current asynchronous implementations (like JS, Rust, etc), any time you use `await` or similar, that statement may never return due to a deadlock in the callstack (A is awaiting B which is awaiting C which is awaiting A).

And if you never `await`, then deadlocking is irrelevant to the _implementation_type_ anyway.

So I am trying to understand what you mean by "it cannot deadlock in this way" - in what way do you mean? async functions can accidentally await on each other without knowing it, which is the deadlock I am talking about.

I think I might understand better if you gave me an example call-chain that, in option 1, sidesteps the deadlock, and in option 2, deadlocks.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#492
post #313

Earlier quoted context omitted.

Debugging rare crashes and heisenbugs is more frustrating, and in non-safe languages, a chronic problem. Whereas after you prove the safety of a design once, it stays with you.

So you use a safe, garbage-collected language like Python, and iterate 5x as fast as Rust. Problem solved. It's 2023 - there are at least a dozen production-quality safe languages.

> and iterate 5x as fast as Rust.

I've been involved in Java, Python, PHP, Scala, C++, Rust, JS projects in my career. I think I'd notice a 5x speed difference in favor of Python if it existed. But I haven't.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#493

Earlier quoted context omitted.

Cheering for your metaverse app. Hope to hear more about it. I suspected you might be doing gamedev but this is the first time you’ve shown extensive work. One challenge with rust is that (for better or worse) most gamedev talent is C++. If you ever open source it I’d be interested in contributing, though I’m not sure how effective the contributions would be. Good luck!

Email sent. I'm not that interested in self-promotion here as I am in getting more activity on Rust graphics development. I think the Rust core graphics ecosystem needs about five good graphics people for a year to get unstuck. Rust is a good language for this sort of thing, but you've got to have reliable heavy machinery down in the graphics engine room. Until that exists, nobody can bet a project with a schedule an…

Any pointers on what exactly is missing?

I am neither a Rust guy or a graphics guy, but I have some interest in what is missing in the ecosystem.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#494

OK, I suppose I should write to this. As I've mentioned before, I'm writing a high performance metaverse client. Here's a demo video.[1] It's about 40,000 lines of Rust so far. If you are doing a non-crappy metaverse, which is rare, you need to wrangle a rather excessive amount of data in near real time. In games, there's heavy optimization during game development to prevent overloading the play engine. In a metavers…

> Async contamination I've always wondered why the "color" of a function can't be a property of its call site instead of its definition . That would completely solve this problem - you declare your functions once , colorlessly, and then can invoke them as async anywhere you want.

The rust guys are working on this very problem with the keyword generics proposal https://blog.rust-lang.org/inside-rust/2022/07/27/keyword-ge...

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#495
post #482

Earlier quoted context omitted.

> So just like any other kind of scheduling? Yes. Industries that care about latency take some pains to avoid this as well, of course. > io_uring and epoll have nothing to do with it and can't avoid the problem: the problem is with code that can make progress and doesn't need to poll for anything. They totally can though? If I write the exact same code that is called out as problematic in the post, my non-preemptive…

>This sort of design solves the problem for any case of "My task that is performing I/O through my runtime is starving my other tasks." Yeah, there's your misunderstanding, you've got it backwards. The problem being described occurs when I/O isn't happening because it isn't needed, there isn't a problem when I/O does need to happen. Think of buffered reading of a file, maybe a small one that fully fits into the buffe…

Reading from a socket, as in the linked post, is an example of not performing I/O? I'm not familiar with tokio so I did not know that it maintained buffers in userspace and filled them before the user called read(), but this is unimportant, it could still have read() yield and return the contents of the buffer.

I assumed that users would issue reads of like megabytes at a time and usually receive less. Does the example of reading from a socket in the blog post presuppose a gigabyte-sized buffer? It sounds like a bigger problem with the program is the per-connection memory overhead in that case.

The proposal is obviously not to yield 1 million times before returning a 1 meg buffer or to call read(2) passing a buffer length of 1, is this trolling? The proposal is also not some imaginary pie-in-the-sky idea; it's currently trading millions of dollars of derivatives daily on a single thread.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#496

Earlier quoted context omitted.

> This is a far superior workflow when you factor in outcomes. I’m a strong-typing enthousiast, too, but still, I’m not fully convinced that’s true. It seems you can’t iterate fast at all in Rust because the code wouldn’t compile, but can iterate fast in C++, except for the fact that the resulting code may be/often is unstable. If you need to try out a lot of things before finding the right solution, the ability to i…

I think mostly you just need less iteration with Rust because the language seems to guide you towards nice, clean solutions once you learn not to fight the borrow checker. Rust programmers don't iterate using unsafe because every single line of unsafe gives you more to think and worry about, not less. But they might iterate using more copying/cloning/state-sharing-with-ref-counting-and-RefCell than necessary, and cle…

The point of iteration is not typically to find the best implementation for a given algorithm, it's to find the best algorithm for solving a given problem.

I can see the argument that Rust encourages by its design a clean implementation to any given algorithm. But no language's design can guide you to finding a good algorithm for solving a given problem - you often need to quickly try out many different algorithms and see which works best for your constraints.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#497
post #402

Earlier quoted context omitted.

> As I've mentioned before, I'm writing a high performance metaverse client. Why? (Serious question)

Started 3 years ago during covid when metaverse looked attractive. In 3 years many of these AI applications will face the same questions.

Will they? AI has adoption already, the metaverse is still waiting for meaningful adoption. You could argue that it’s never coming.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#498
post #482

Earlier quoted context omitted.

>This sort of design solves the problem for any case of "My task that is performing I/O through my runtime is starving my other tasks." Yeah, there's your misunderstanding, you've got it backwards. The problem being described occurs when I/O isn't happening because it isn't needed, there isn't a problem when I/O does need to happen. Think of buffered reading of a file, maybe a small one that fully fits into the buffe…

Reading from a socket, as in the linked post, is an example of not performing I/O? I'm not familiar with tokio so I did not know that it maintained buffers in userspace and filled them before the user called read(), but this is unimportant, it could still have read() yield and return the contents of the buffer. I assumed that users would issue reads of like megabytes at a time and usually receive less. Does the examp…

You're confusing IO not happening because it's not needed with IO never happening. Just because a method can perform IO doesn't mean it actually does every time you call it. If I call async_read(N) for the next N bytes, that isn't necessarily going to touch the IO driver. If your task can make progress without polling, it doesn't need to poll.

>I'm not familiar with tokio so I did not know that it maintained buffers in userspace

Most async runtimes are going to do buffering on some level, for efficiency if nothing else. It's not strictly required but you've had an unusual experience if you've never seen buffering.

>filled them before the user called read()

Where did you get this idea? Since you seem to be quick to accuse others of it, this does seem like trolling. At the very least it's completely out of nowhere.

>it could still have read() yield and return the contents of the buffer.

If I call a read_one_byte, read_line, or read(N) method and it returns past the end of the requested content that would be a problem.

>I assumed that users would issue reads of like megabytes at a time and usually receive less.

Reading from a channel is the other easy example, if files were hard to follow. The channel read might implemented as a quick atomic check to see if something is available and consume it, only yielding to the runtime if it needs to wait. If a producer on the other end is producing things faster than the consumer can consume them, the consuming task will never yield. You can implement a channel read method that always yields, but again, that'd be slow.

>The proposal is obviously not to yield 1 million times before returning a 1 meg buffer, is this trolling

No, giving a illustrative example is not trolling, even if I kept the numbers simple to make it easy to follow. But your flailing about with the idea of requiring gigabyte sized buffers probably is.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#499

We do not want red and blue functions. Any language that implements async / await as coroutines instead of green threads is making a fundamental CS mistake. https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... Concurrency's correct primitive is Hoare's Communicating Sequential Processes mapped onto green threads. Some languages that have it right are Java (since JDK17 - Java Virtual Threads), Go, Kotlin.

Maybe the issue is that we overload the concept of a function with an entirely different thing, a Future / Promise. Maybe if the syntax would have been entirely different too, it would have been easier to understand. We tend to have different syntax for different things.

I’m hesitant towards not distinguishing different things anymore and let the underlying system “figure it out”. I’m sure this could work as long as you’re on the happy path, but that’s not the only path there is.

Re: Maybe Rust isn’t a good tool for massively concurrent, userspace software

#500

OK, I suppose I should write to this. As I've mentioned before, I'm writing a high performance metaverse client. Here's a demo video.[1] It's about 40,000 lines of Rust so far. If you are doing a non-crappy metaverse, which is rare, you need to wrangle a rather excessive amount of data in near real time. In games, there's heavy optimization during game development to prevent overloading the play engine. In a metavers…

What you've just described is basically every networked video game, the majority of which are happily running via c++.

(Plus some increase in content load over the network, which does exist ala runtime mod loading, streaming, etc)

Post reply on HN