From the manual: Currently, all tasks in Julia are executed in a single OS thread co-operatively.
As an EE with a bit of OS knowledge, my transcription is:
Currently, all tasks run on a single thread: the CPU sees all tasks as a single program that executes serially. In order for each task to be given a chance to run, the tasks need to co-operate, which means they need to yield
every once in a while. wait
ing, performing I/O and sleep
ing imply yield
.
Hmm, so how would I get the tasks to run in parallel, if they all had to share a single thread?
Btw, I know of @spawn
, but it isnāt clear to me how it correlates with the sentence in the OP.
With only a single OS thread, there is no āin parallelā, at least not in the sense that two tasks execute a step in their respective code at the exact same time. With one thread, only one task can make progress at a time. The two tasks can however execute concurrently, that is they can each execute for a bit, then yield
to the other task, let it execute for a bit, then switch back etc. until both are done executing. One classic example is how your OS is able to run more programs āat the same timeā than it has hardware threads available for execution - this is also concurrency. See also here. Youāll also find plenty of ressources when you search for concurrency vs. parallelism
online.
I might be splitting hairs, but that sounds more like time-sharing then concurrency.
Itās probably a similar concept, but itās named from the level of abstraction of your program - as far as your code is concerned, both are happening side by side. Most useful for when one task has to wait (e.g. for data to load from hard drive, network operation) but the other doesnāt.
But if neither has opportunity to wait (e.g. your tight inner loops), thereās not much benefit to single-thread concurrency.
I think the āCurrentlyā means that in theory, tasks could be executed on different threads, potentially having the best of both worlds. But thatās presumably a lot more complicated to manage efficiently.
That passage from the manual dates back to the dark ages (< v1.3
) when all Task
s ran on a single thread (managed by libuv
, IIRC), i.e., before they could be scheduled for simultaneous execution on Julia-runtime threads.
Ah, that makes more sense now. Thanks.