News for hackers. Stuff that matters.
Re:Ruby 3.0 and the new FiberScheduler interface by WJW on Tuesday December 29, 2020 @04:09PM (#25575051)
(Author here)

I kinda agree but yielding only on I/O is not enough IMO. Sooner or later we'll want to do CPU intensive work in fibers as well, which in the current implementation will block all other fibers on the same thread. Like I mentioned in the article, I'd like to see work stealing between different threads as that would allow fibers to migrate away from threads stuck in CPU intensive work. An alternative way could be to adopt a model similar to Haskells lightweight threads, where the runtime forces a `yield` after N milliseconds (configurable). That would make sure that CPU intensive work would not block other fibers "too" much.

Re:Ruby 3.0 and the new FiberScheduler interface by anonacct38 on Tuesday December 29, 2020 @04:33PM (#25575319)
Go's journey here has been interesting. Early on it was possible (though rarely seen in practice) to end up with a cpu bound thread not yielding because it didn't hit yield point like I/O.

Then they added a guarantee that if your loop called a function, the scheduler would be able to make the goroutine yield. https://golang.org/doc/go1.2#preemption

This mostly worked although you could still have a CPU-bound thread not making any function calls. I also personally ran into a pathological issue where the scheduler was being invoked, but a heuristic kept the current goroutine running so others were still starved.

Finally they added true pre-emption (not yielding) in 1.14 https://golang.org/doc/go1.14#runtime it looks like it just sends signals and saves state.

Once nice thing is that if I understand the go runtime correctly, work stealing by scheduling goroutines on different threads has been a thing for a long time.

Re:Ruby 3.0 and the new FiberScheduler interface by nesarkvechnep on Tuesday December 29, 2020 @04:31PM (#25575299)
This is not only the way Haskell's scheduler work but also Erlang VM's. Not completely the same because the BEAM scheduler uses reductions instead of time but both scheduling schemes can be classified as preemptive. Since fibers are cooperatively scheduled I don't believe the core developers of Ruby would just agree to switch the scheduling scheme.
Re:Ruby 3.0 and the new FiberScheduler interface by matheusmoreira on Tuesday December 29, 2020 @10:21PM (#25578069)
> Sooner or later we'll want to do CPU intensive work in fibers as well, which in the current implementation will block all other fibers on the same thread.

This limitation is present in every modern asynchronous programming system I've ever seen. They simply can't deal with long function calls. There's a loop under the hood which constantly executes queued functions. Any long-running function will stall the execution pipeline and increase latency. It's just like cooperative multitasking...

Re:Ruby 3.0 and the new FiberScheduler interface by Rapzid on Tuesday December 29, 2020 @10:35PM (#25578157)
Golang, .Net, and BEM all use preemptive scheduling IIRC. Don't know the specifics of each implementation, but you can use timers to signal the process and "wake" the scheduler.
Re:Ruby 3.0 and the new FiberScheduler interface by masklinn on Wednesday December 30, 2020 @02:11AM (#25579375)
Beam uses reduction, basically instructions count. I believe native functions can still lock up a scheduler (and must provide an estimate of their icount) which is one of the reasons why they’re tricky.
Re:Ruby 3.0 and the new FiberScheduler interface by valenterry on Tuesday December 29, 2020 @10:37PM (#25578177)
That depends. A long-running function is usually just a semantically long running function which consists of multiple (usually suspendable) parts. Of course there are exceptions, such as long running cpu heavy calculations for which a single atomic call takes longer than just milliseconds. But I think this is rather rare.

And for just semantically long running functions, it is not difficult to write a scheduler that tries to be "fair", however you want to interpret that. But of course it requires to fully embrace asynchronous programming, something that will probably difficult in Ruby.

Re:Ruby 3.0 and the new FiberScheduler interface by hamandcheese on Wednesday December 30, 2020 @01:16AM (#25579103)
Ruby already handles this for regular threads by setting a timer for how long one thread can hold the GVL, doesn’t it? Could the same thing work for fibers? I.e. could the ruby vm inject a yield into a running fiber after every 100ms?