Cooperative vs preemtive scheduling of virtual theads

Andrey Lomakin lomakin.andrey at gmail.com
Thu Jun 11 06:56:34 UTC 2020


Thank you. Appreciate your help.

On Tue, Jun 9, 2020 at 1:43 PM Ron Pressler <ron.pressler at oracle.com> wrote:

>
> While exploiting single-core multitasking is certainly useful at times, it
> is
> clearly very niche, so if there's ever a conflict between improving the
> experience of using virtually-unlimited threads and improving the
> experience of
> single-core multitasking, we will prefer the former.
>
> Having said that, I think that the two are not in conflict, especially
> when we
> consider that those who wish to take advantage of the benefits of
> single-core
> multitasking are expert users who will hopefully take great care to get it
> right. Unless you choose a scheduler that employs forced "external"
> preemption,
> it will not occur in any place where publishing inconsistent data
> structures
> does not already introduce issues today. Class loading can run *arbitrary*
> code
> that you cannot possibly inspect, and it, therefore, already potentially
> causes
> whatever issues making it a scheduling point would. However, if you can
> find an
> example where it, or some other platform mechanism, does introduce new
> issues if
> it were made a scheduling point, we will certainly consider promising it
> won't
> be.
>
> — Ron
>
>
> On 9 June 2020 at 09:16:24, Andrey Lomakin (lomakin.andrey at gmail.com
> (mailto:lomakin.andrey at gmail.com)) wrote:
>
> > > For one, even if we guaranteed class loading doesn't introduce a
> scheduling
> > > point, you wouldn't be able to rely on HashMap code not having any,
> because the
> > > existence of such scheduling points are a hidden implementation detail
> of
> > > HashMap that could change from one version to another. That's because
> scheduling
> > > is not cooperative, and code is not made aware of scheduling point in
> code it
> > > calls via, say, the type checker. The reason scheduling isn't
> cooperative is
> > > that that would have resulted in a split world, duplicate APIs and no
> forward
> > > compatibility. So you cannot rely on third-party code not having
> scheduling
> > > points regardless of class loading.
> >
> > Sure, that is why I want to understand/discuss the level of abstraction
> on which Loom project works "by design" so to say.
> >
> > As I can see it, there are two possible variants for the case when a
> single thread carrier is used. The first preemption can be performed only
> in the places which are visible for the developer from inspection of source
> code. Like lock/unlock and IO calls. Sure there is no control over the code
> directly by the developer where a developer can introduce the "wait"
> keyword (but Thread.yield in current implementation looks very close to
> such method). But this approach allows developer, who wants to create code
> as performant as possible, to have more control on insertion of memory
> fences in one form or another to ensure data consistency. It also opens the
> way to use for example collections of primitive types and data structures
> which otherwise would be very hard to use. Sure you can not tell by the
> signature of the function whether it can be used by several virtual threads
> or not, but it seems quite unlikely that HashMap will become unsafe
> eventually as the other in-memory data structures. Also, once the concept
> of virtual threads is introduced possibility or absence of possibility to
> use data structure inside of virtual threads will be reflected inside of
> its contract. ConcurrentHashMap is declared to be thread-safe not because
> of type checker inspection, obviously, but because that is a part of its
> contract. The other approach is to introduce scheduling points in the
> "hidden" places like loading of class or maybe some other JVM
> implementation dependant parts of the code. The last case means that
> essentially you work with virtual threads as with normal threads with the
> exception of the fact that the amount of them is virtually unlimited, which
> is itself a big advantage of course.
> >
> > Each approach has its advantages and disadvantages. I hope that probably
> you may consider using the first of described approaches (with scheduling
> points are clearly recognisable from inspection of source code), especially
> taking in account that right now, as I can see the state of the
> implementation, exactly this approach is used but with theoretical bound to
> handle "hidden" scheduling points too. Even if in such hidden points
> virtual threads will not be switched, I dare to suppose that they happen so
> rarely on JDK implementations that it will not affect scalability or
> performance numbers at all.
> >
> > In any way or another Loom is very big step forward for the Java world.
> Hope to see it included into primary branch of JDK ASAP.
> >
> >
> >
> >
> > On Tue, Jun 9, 2020 at 7:15 AM David Holmes wrote:
> > > On 9/06/2020 12:52 am, Ron Pressler wrote:
> > > > You should not make any assumptions about where scheduling points
> are. Thread.yield
> > > > is not currently specified, but we *may* specify it so that it
> guarantees returning
> > > > to the scheduler.
> > > >
> > > > You *can* assume that a virtual thread is scheduled by its assigned
> scheduler.
> > > > Therefore, if a scheduler makes use of a single thread, your memory
> accessed are
> > > > fully-ordered, and you can then use, say, HashMap instead of
> ConcurrentHashMap for
> > > > threads scheduled by that scheduler. For more interesting
> synchronisation among your
> > > > threads, you can use locks, which are quite fast when uncontended.
> > >
> > > But I would not advise/encourage programmers to make any general
> > > assumptions about what scheduler (and its characteristics) may be
> > > managing their virtual threads. Concurrency-safety for shared objects
> > > should be achieved through appropriate synchronization mechanisms, not
> > > by relying on a thread not being preempted within a critical region.
> > >
> > > Cheers,
> > > David
> > > -----
> > >
> > > > Could you give an example where this could be insufficient?
> > > >
> > > > — Ron
> > > >
> > > >
> > > >
> > > > On 8 June 2020 at 14:48:55, Andrey Lomakin (lomakin.andrey at gmail.com
> (mailto:lomakin.andrey at gmail.com)(mailto:lomakin.andrey at gmail.com)) wrote:
> > > >
> > > >>> For
> > > >>> example, any call might be to code that loads new classes, thus
> > > >>> blocking. So, in principle, any call site can switch tasks.
> > > >>
> > > >> And one more question, is it situation which described by Andrew
> really holds ? I thought that executors by current design does not
> recognize such situations (which for example causes the current problem
> with synchronized)
> > > >> and do not switch execution of virtual theads and that happens
> during direct calls to the locks and during calls of IO operations ? And is
> it possible that this behaviour will be kept as the "by design" or can be
> changed once project will evolve ? I mean is it true that during exectuion
> of such operation as class loading execution of one virtual thread will be
> swithced to the execution of other virtual thread, especially if the backed
> by the single thread carrier ?
> > > >>
> > > >>
> > > >> On Mon, Jun 8, 2020 at 4:33 PM Andrey Lomakin wrote:
> > > >>> Hi,
> > > >>> Thank you for the very useful feedback.
> > > >>>
> > > >>>> Does Thread.yield have defined semantics for virtual threads?
> > > >>>
> > > >>> That is exactly question which I wanted to ask too. Becuase in
> quasar its implementation looked close to the "wait" key word when you give
> up processor time to the other waiting virtual thread.
> > > >>>
> > > >>> As for feedback , I have made migration just a few days ago. Which
> was a quite smooth.
> > > >>> So I did not run benchmarks yet. But on some of the tests I see
> about 1.5 times speed up (the ones which generate high rate of asynchronous
> calls to the file IO).
> > > >>>
> > > >>
> > > >>
> > > >>
> > > >>
> > > >> --
> > > >> Best regards,
> > > >> Andrey Lomakin.
> > > >>
> > > >
> >
> >
> > --
> > Best regards,
> > Andrey Lomakin.
> >
>
>

-- 
Best regards,
Andrey Lomakin.


More information about the loom-dev mailing list