Strange interaction with hyperthreading on Intel hybrid CPU

Michael van Acken michael.van.acken at
Tue Oct 10 11:52:15 UTC 2023

Am Di., 10. Okt. 2023 um 12:56 Uhr schrieb Alan Bateman <
Alan.Bateman at>:

> [...]
> Are the virtual threads executing compilation tasks in this usage? How
> many of them are running concurrently? I'm trying to see if this is a
> good use of virtual threads or not.

There are three kinds of threads involved that vary somewhat in their

* A namespace thread starts with I/O reading the source file, parses it,
then starts processing forms.  If the namespace begins with imports of
unseen or unfinished namespaces this thread blocks almost immediately,
otherwise it compiles top-level content of the file and starts threads for
every function it encounters.  With most action happening in functions,
this kind of thread is not CPU heavy.  Because of imports and macro
expansion, it may have to wait for tasks to complete at unpredictable

* Function threads typically cover a smaller scope of text, handle the
conversion to the intermediate representation, and recursively start
threads for nested functions.  Short lived, they do the bulk of the
compilation work, and send of their results into a queue.  If unfinished
macros are involved, they may block as well.  These threads account for the
bulk of the thread count, say >80%.

* Every namespace thread is accompanied by an emitter thread that assembles
the pieces send over by the two prior kinds, decides on the higher level
translation patterns, generates class files via the Class-file API, and
defines them into the appropriate classloader.  My impression is that this
kind of thread is mostly waiting, with short bursts of action whenever a
class file must be generated.

None of these thread kinds is particular cpu heavy, each may block because
some prior compilation steps must complete first, and there is only
moderate I/O involved (both Clojure input files and class files tend to the
smaller side).

As for how many are running in parallel, I can only say: it varies.  For
example, the bootstrap scenario starts with the core library (the largest
input file of all), and nothing else can be started until this is
finished.  Afterwards the compiler can go wider and work on several
namespaces in parallel, but this depends on how these are interrelated.

> On HT, this is a good topic. We've had one report where limiting the
> number of carrier threads to half the number of hardware threads
> improved performance. I think we need more usage on these systems to see
> if the ergonomics and defaults should be tuned for these processors.

Is there a way to change the number of carrier threads?  Something like
"this line in this .java file" would suffice for me to make images and
compare the effect.

-- mva
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the loom-dev mailing list