Hacker News new | past | comments | ask | show | jobs | submit login

The JVM has shown that copying the stackframes can be magnitudes more efficient then context switching via separate threads. Likely, Rust's implementation would look different but this route seems too promising not to do basic research on.

I mean, is there anybody who seriously thinks that colored functions is the holy grail?




Just last month .NET ended a green threading experiment, mainly because the overhead it adds to FFI was too high: https://github.com/dotnet/runtimelab/issues/2398

Rust had green threads until late 2014, and they were removed because of their impact on performance.

Everyone has done the basic research: green threading is a convenient abstraction that comes with certain performance trade offs. It doesn't work for the kind of profile that Rust is trying to target.


The performance tradeoffs are very different for different languages. In Java, virtual threads add no FFI costs and virtually no performance impact not because the baseline is lower but because memory management in Java is just so incredibly efficient these days (although that does come at the cost of a higher footprint). So the impact and the tradeoffs are not the same. Allocating heap memory in a very general way is simply faster -- even in absolute terms -- in Java than in a low-level language. Java, unlike .NET or Rust, also doesn't allow pointers into the stack, so we can do very efficient copying "in the shadow" of cache misses, and that takes care of FFI.


> also doesn't allow pointers into the stack, so we can do very efficient copying "in the shadow" of cache misses

How does this work?


First, the use-case where virtual threads offer the most benefit is servers with high concurrency (due to Little's law https://youtu.be/07V08SB1l8c?si=rwTQrnHBnp4NGrj7), which means we're talking about a very large number of threads. That, in turn, means that the state of all those threads cannot fit in the CPU cache, so even the most efficient implementation possible, i.e. one that simply changes the sp register to point to a new stack will incur an expensive cache miss. That means that copying small sections of the stack is almost free (because a cache miss+copy isn't all that more expensive than just a cache miss).

Copying portions of the stack means that you can continue executing code directly in OS threads (rather than change the stack pointer), so the overhead for FFI is zero. However, you cannot copy portions of stack if there are pointers into the stack. In .NET and in low-level languages there are pointers into the stack which makes copying inefficient. Furthermore, managing these stack portions efficiently in the heap requires extremely efficient dynamic memory management, which is something that languages with good GCs do better than low-level languages with more direct memory management.


Yup, the ffi cost is extremely painful. I work on a Go product that is performance sensitive and this exact problem is a constant source of aggravation


Rather than green threads effectiveness in general dotnet experiment proves that sometimes early design decisions are pervasive enough to simply not allow efficient/economical way of moving to new paradigm.

And yes I agree Rust has its own application domain and they are perfectly right to do things as they see fit.


> The JVM has shown that copying the stackframes can be magnitudes more efficient then context switching via separate threads.

...when there's literally no work in those threads whatsoever, that is. Unless you have something more substantial than the many "benchmarks" out there that are "look, spawning 10 bajillion virtual threads that don't do anything at all but sleep is now super efficient"?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: