You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently Picos defines an effect Current that Fiber.current () performs to obtain the "handle" of the current fiber from the scheduler.
Semantically this makes sense. I don't see anything wrong with this design in a logical sense.
However, it turns out that, by using thread-local storage or TLS, the same ability, to obtain the handle of the current fiber, could be at least about 3x and up to about 6x faster.
On my laptop, it is possible to obtain the value associated with a key in TLS more than 240 M/s (million times per second) while obtaining the current fiber with an effect can be done about 40 M/s. So, roughly speaking, TLS.get current_fiber_key (hidden inside Fiber.current ()) could be up to 6x faster. If we assume setting the key (by the scheduler) takes roughly comparable time, then even if there is a fiber switch between every Fiber.current () it could still be up to about 3x faster to use TLS rather than an effect.
The fiber handle obtained via Fiber.current () is used for several purposes, including
to obtain an identity for the current fiber,
to change the state of whether propagation of cancelation is forbidden or permitted, and
to access the fiber-local storage or FLS.
The fiber identity is important for the implementation of error checking concurrent abstractions. For example, a mutex implementation could obtain the identity of the current fiber, store that with the mutex when locking, and check that the mutex is unlocked by the same fiber.
Some concurrent abstractions need to explicitly forbid the propagation of cancelation for correctness. For example, the wait operation of an implementation of condition variables matching the signature of condition variables in the OCaml Stdlib needs to lock the associated mutex before returning or raising an exception — even in case the fiber has been canceled. To obtain a mutex the fiber may need to be suspended and when propagation of cancelation is permitted a typical scheduler would propagate the cancelation to the fiber at that point instead of allowing the fiber to obtain the mutex.
Fiber-local storage could, for example, be used to associate a message queue in an actor implementation with each fiber / actor. Actors communicate by sending and receiving message and any additional overhead needed to obtain the message queue of the current fiber will directly affect the performance of an actor implementation.
The question is, should we keep on using effects and accept the lower performance or should we use the less elegant but better performing apporach to use TLS to store handle to the current fiber?
I personally feel that we should investigate the use of TLS and likely avoid using effects for Fiber.current (), because something like a 4x performance cost is significant enough that people are motivated to avoid it — which could jeopardize the goal of interoperability. My opinion on this is open, however. In some cases it is possible to amortize the cost by keeping the fiber handle in a local variable, but that also brings some problems and potentially makes programming more cumbersome.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Currently Picos defines an effect
Current
thatFiber.current ()
performs to obtain the "handle" of the current fiber from the scheduler.Semantically this makes sense. I don't see anything wrong with this design in a logical sense.
However, it turns out that, by using thread-local storage or TLS, the same ability, to obtain the handle of the current fiber, could be at least about 3x and up to about 6x faster.
On my laptop, it is possible to obtain the value associated with a key in TLS more than 240 M/s (million times per second) while obtaining the current fiber with an effect can be done about 40 M/s. So, roughly speaking,
TLS.get current_fiber_key
(hidden insideFiber.current ()
) could be up to 6x faster. If we assume setting the key (by the scheduler) takes roughly comparable time, then even if there is a fiber switch between everyFiber.current ()
it could still be up to about 3x faster to use TLS rather than an effect.The fiber handle obtained via
Fiber.current ()
is used for several purposes, includingThe fiber identity is important for the implementation of error checking concurrent abstractions. For example, a mutex implementation could obtain the identity of the current fiber, store that with the mutex when locking, and check that the mutex is unlocked by the same fiber.
Some concurrent abstractions need to explicitly forbid the propagation of cancelation for correctness. For example, the
wait
operation of an implementation of condition variables matching the signature of condition variables in the OCaml Stdlib needs to lock the associated mutex before returning or raising an exception — even in case the fiber has been canceled. To obtain a mutex the fiber may need to be suspended and when propagation of cancelation is permitted a typical scheduler would propagate the cancelation to the fiber at that point instead of allowing the fiber to obtain the mutex.Fiber-local storage could, for example, be used to associate a message queue in an actor implementation with each fiber / actor. Actors communicate by sending and receiving message and any additional overhead needed to obtain the message queue of the current fiber will directly affect the performance of an actor implementation.
The question is, should we keep on using effects and accept the lower performance or should we use the less elegant but better performing apporach to use TLS to store handle to the current fiber?
I personally feel that we should investigate the use of TLS and likely avoid using effects for
Fiber.current ()
, because something like a 4x performance cost is significant enough that people are motivated to avoid it — which could jeopardize the goal of interoperability. My opinion on this is open, however. In some cases it is possible to amortize the cost by keeping the fiber handle in a local variable, but that also brings some problems and potentially makes programming more cumbersome.Beta Was this translation helpful? Give feedback.
All reactions