News for hackers. Stuff that matters.
Re:Composable multi-threaded parallelism in Julia by StefanKarpinski on Tuesday July 23, 2019 @05:08PM (#20510217)
It's hard to overstate what a big deal this is (and how much effort went into it). The only mainstream languages with this kind of composable parallelism are Go and Erlang, both of which target writing servers, rather than high-performance computing, and which therefore optimize for I/O throughput rather than CPU throughput.

The only systems which have supported compute-oriented composable parallelism like this are Cilk and TBB, which are both really excellent and successful—and provided major inspiration for this work. However, they both seem to have fallen short of widespread adoption partly due to being non-free (until recently) and also, I suspect, because they are non-standard C/C++ language/compiler extensions, which seem to never catch on that broadly.

This is a brave new world for high-performance technical computing, not just for Julia.

Re:Composable multi-threaded parallelism in Julia by pka on Tuesday July 23, 2019 @07:24PM (#20511101)
For completeness' sake, Haskell has had this for over a decade :) A SO thread that gives a nice overview [0], the paper [1], the library [2]. Here's how a parallel fib looks like:

  fib :: Int -> Int
  fib n
    | n <= 1    = 1
    | otherwise = x ‘par‘ (y ‘pseq‘ x + y + 1)
    where
      x = fib (n-1)
      y = fib (n-2)
[0] https://stackoverflow.com/questions/958449/what-is-a-spark-i...

[1] http://simonmar.github.io/bib/papers/strategies.pdf

[2] http://hackage.haskell.org/package/parallel-3.2.2.0/docs/Con...

Re:Composable multi-threaded parallelism in Julia by cygx on Wednesday July 24, 2019 @09:08AM (#20514836)
Perl6 also has been able to do this for a couple of years:

    sub fib(Int $n) {
        return $n if $n < 2;
        my $t = start { fib($n - 2) }
        fib($n - 1) + await($t);
    }
Re:Composable multi-threaded parallelism in Julia by pkofod on Tuesday July 23, 2019 @11:18PM (#20512149)
For complete completenes sake, Haskell has existed for almost three decades :)
Re:Composable multi-threaded parallelism in Julia by dwohnitmok on Wednesday July 24, 2019 @01:28AM (#20512566)
While the earliest versions of Haskell date back that far, those combinators only came out in 2007 (IIRC).
Re:Composable multi-threaded parallelism in Julia by chrisseaton on Wednesday July 24, 2019 @02:45AM (#20512858)
Those functions weren’t part of Haskell back then.
Re:Composable multi-threaded parallelism in Julia by pkofod on Wednesday July 24, 2019 @02:55PM (#20518431)
What do you mean? That's my point exactly. While Haskell has that now, they didn't always have it.

If a programming language is created in 2019 they can certainly instantly incorporate insights from existing technology in their design an plans. However, that doesn't mean that any programming language/compiler project started today will instantly have all of those features. Things take time in each new framework.

Re:Composable multi-threaded parallelism in Julia by chrisseaton on Wednesday July 24, 2019 @06:15PM (#20520520)
I don't know what your point is, then.

Haskell didn’t have it originally. Ok. But what do you think that says about whether it’s a new idea or not? What’s the connection? Why mention it in this thread about whether it's a new idea or not?

Re:Composable multi-threaded parallelism in Julia by StefanKarpinski on Thursday July 25, 2019 @12:49AM (#20522638)
At what point did anyone claim it was a new idea? The blog post cites prior art in the very first paragraph. Not in a footnote—in the main text. The top post here cites several other languages with a similar model. This entire thread reads like a bunch of dudes who are really dying to "well, actually" someone.
Re:Composable multi-threaded parallelism in Julia by chrisseaton on Thursday July 25, 2019 @04:37AM (#20523673)
I think people were responding to

> The only systems which have supported compute-oriented composable parallelism like this are Cilk and TBB

Because it isn’t true. Haskell is an example of why it isn’t true.

Re:Composable multi-threaded parallelism in Julia by StefanKarpinski on Friday July 26, 2019 @05:57PM (#20538707)
It's extremely debatable that Haskell is compute-oriented. I know that Haskell people like to talk about doing numerical computing in Haskell, but in reality it does not seem to be a thing. No one has ever used Haskell to implement large scale scientific computations on supercomputers, for example.
Re:Composable multi-threaded parallelism in Julia by tavert on Friday July 26, 2019 @07:41PM (#20539275)
Re:Composable multi-threaded parallelism in Julia by DNF2 on Monday July 29, 2019 @09:48AM (#20554537)
This particular example appears to be an implementation of a 'Computer algebra system', which seems to be a type of symbolic computing rather than numerical computing.
[dead]
Re:Composable multi-threaded parallelism in Julia by tavert on Sunday July 28, 2019 @08:00PM (#20550519)
You're really asking for a Dan Luu sequel here.
Re:Composable multi-threaded parallelism in Julia by thekhatribharat on Tuesday July 23, 2019 @05:56PM (#20510586)
> this kind of composable parallelism are Go and Erlang, ... which therefore optimize for I/O throughput rather than CPU throughput

Parallelism is always for CPU throughput, precisely why you don't run any more OS threads than the number of cores.

Concurrency primitives (whether in Go, Erlang or any other programming language) are meant for I/O-bound tasks. Let's not conflate concurrency primitives enabling I/O-bound tasks and parallelism primitives enabling CPU-bound tasks.

Re:Composable multi-threaded parallelism in Julia by chrisseaton on Tuesday July 23, 2019 @07:52PM (#20511229)
> precisely why you don't run any more OS threads than the number of cores

It’s often worth running more than your number of cores, in order to keep execution units busy during memory fetches for example, or integer units busy while float units are a bottleneck otherwise. (Did a PhD partially on this kind of thing.)

Re:Composable multi-threaded parallelism in Julia by BubRoss on Tuesday July 23, 2019 @08:18PM (#20511342)
That's what hyperthreading is for, which implies having the same number of threads as logical cores.

Hyperthreading and out of order execution are meant to accomplish keeping the execution units busy.

Re:Composable multi-threaded parallelism in Julia by chrisseaton on Tuesday July 23, 2019 @08:39PM (#20511430)
No it implies having the same number of OS threads as hardware threads, which is more than the number of hardware cores.
Re:Composable multi-threaded parallelism in Julia by BubRoss on Wednesday July 24, 2019 @12:14AM (#20512320)
That's what logical cores means. Hardware threads / hyper threads are also called logical cores by the bios and OS.
Re:Composable multi-threaded parallelism in Julia by gpderetta on Wednesday July 24, 2019 @09:13AM (#20514880)
You are obviously correct and I'm not sure why you are being downvoted.
Re:Composable multi-threaded parallelism in Julia by elcritch on Tuesday July 23, 2019 @07:16PM (#20511067)
You can still use Erlang style concurrency (or Go style as well) to truly parallelize CPU bound tasks. It’s a bit less efficient due to Erlangs design where you can’t readily share mutable data between processes but will still enable true parallel calculations on all cores. By default BEAM runs one execution thread per core. For example, it’d be trivial to write a true parallel merge sort in Erlang/Elixir.

Now NodeJS or Python Asio style concurrency _are_ truly limited by their VMs and can’t do native parallel computations in a single process.

Re:Composable multi-threaded parallelism in Julia by phillipcarter on Tuesday July 23, 2019 @07:35PM (#20511162)
(Since this is basically now a comment where everyone "me too"s in a reply...)

F# also has facilities for this, depending on what you're after. The _MailboxProcessor_ type, though not as "for real" as the green threading in Go, allows for some pretty high throughput with a relatively sane message-passing abstraction.

And .NET itself offers many means to do parallel programming (which can get quite optimized), of which F# has some nice abstractions for.

So I don't think it's quite fair to say that only Go and Erlang have good support for parallelism. I also don't think they use their abstractions typically for parallelism (but I good be wrong).

Re:Composable multi-threaded parallelism in Julia by kgwgk on Wednesday July 24, 2019 @02:47AM (#20512865)
> (Since this is basically now a comment where everyone "me too"s in a reply...)

Related work in Common Lisp:

https://github.com/pcostanza/claws/

https://european-lisp-symposium.org/static/2014/costanza.pdf

Re:Composable multi-threaded parallelism in Julia by DNF2 on Wednesday July 24, 2019 @03:13AM (#20512958)
He didn't really say that, though, rather that just Go and Erlang has a similar kind of _composable_ parallelism. (Don't know about Haskell.)
Re:Composable multi-threaded parallelism in Julia by nickpeterson on Tuesday July 23, 2019 @08:25PM (#20511381)
That name though, couldn't it just be Agent?
Re:Composable multi-threaded parallelism in Julia by eigenspace on Tuesday July 23, 2019 @05:20PM (#20510315)
As a physicist, it's been really cool seeing the awareness of Julia in the community gradually increase.

Large swathes of the physics community have been migrating their code to Python over the past few years but it really seems now that Julia is getting so many amazing features and packages that it can't be ignored.

Re:Composable multi-threaded parallelism in Julia by benjaminva on Wednesday July 24, 2019 @02:39AM (#20512831)
Same here, I worked in a computational biophysics department with lots of python/bash/R and I was the only one who wrote lots of high-performance code in Julia. People were curious about the language but it was still very much unknown. Hope we will see a broader adoption of Julia in the future - it's just that much better for the stuff we do on a daily basis.
Re:Composable multi-threaded parallelism in Julia by conjectures on Tuesday July 23, 2019 @05:51PM (#20510541)
Great to see this finally land - thanks for all the team's work. Looking forward to giving it a whirl.

Threading is something of a prerequisite for acceptance as a serious language among many folks. So great to not just check that box, but to stick the pen right through it.

The devil is always in the details, but from the doc the interface looks pretty nice (given threaded code generally looks like it was written by Cthulhu).

Re:Composable multi-threaded parallelism in Julia by KenoFischer on Tuesday July 23, 2019 @05:52PM (#20510551)
> given threaded code generally looks like it was written by Cthulhu

Whereas in Julia, we use Cthulhu to read code ;) - https://github.com/JuliaDebug/Cthulhu.jl.

Re:Composable multi-threaded parallelism in Julia by chrisseaton on Tuesday July 23, 2019 @07:44PM (#20511203)
This is a bit over the top isn’t it? It’s just task parallelism. It’s exactly what for example Haskell has been doing for decades isn’t it? It’s even the same demo and interface!
Re:Composable multi-threaded parallelism in Julia by DNF2 on Wednesday July 24, 2019 @03:22AM (#20512994)
My understanding is that it's not just about the parallelism, but about the type of threading model that is used, which makes it extremely composable.
Re:Composable multi-threaded parallelism in Julia by tomp on Wednesday July 24, 2019 @07:14AM (#20513991)
It's literally just futures. (Still very hard to implement, of course, and in particular IMO this kind of implementation (M-to-N threading) is much better than the async/await implementations) but CS is pretty settled on futures being the "best" model, even C++ has them!)
Re:Composable multi-threaded parallelism in Julia by DNF2 on Wednesday July 24, 2019 @09:05AM (#20514806)
My understanding was that the depth-first scheduling was basically 'new'.
Re:Composable multi-threaded parallelism in Julia by chrisseaton on Wednesday July 24, 2019 @09:24AM (#20514994)
In my experience most work-stealing schedulers for task parallelism like this are going to be depth-first. I’ve written several myself. Primarily for temporal locality - if you just created a task it’ll be resident in cache.
Re:Composable multi-threaded parallelism in Julia by gpderetta on Wednesday July 24, 2019 @09:54AM (#20515270)
I'm still trying to access the relevant papers, but from bits of discussions here it seems to me that the difference between the Julia scheduler and cilk is that the former will try to distribute sibling leaf tasks among executors enforcing as close as a global depth first view as possible, while cilk does depth first on each executor but different executors will be exploring distinct the problem space branching off as close to the root as possible (due to the steal the oldest ancestor behaviour). It is a compromise between better cross executor cache locality and increased contention I guess.
Re:Composable multi-threaded parallelism in Julia by gpderetta on Wednesday July 24, 2019 @10:08AM (#20515406)
Futures in c++ are really meant for concurrency especially for IO. They currently are way too heavy weight for fine grained parallelism (although there is work ongoing on that). Also futures are about packaging tasks, all the stuff being discussed here is about optimal scheduling which is completely orthogonal.
Re:Composable multi-threaded parallelism in Julia by scott_s on Tuesday July 23, 2019 @05:57PM (#20510591)
Do people use Cilk heavily in the high-performance computing world? They did not when I was part of it. I think OpenMP (https://www.openmp.org/) is what more people would reach for. It started as a way to parallelize loops, but has had a task framework for a long time which I believe also allows composeable parallelism.

OpenMP, however, depends on not just compiler extensions, but pragmas, so it tends to not find traction outside of the HPC world.

Re:Composable multi-threaded parallelism in Julia by gpderetta on Wednesday July 24, 2019 @07:10AM (#20513960)
While extremely elegant and minimalistic, I do not think cilk ever gained much traction. GCC has deprecated it and is removing it. I think that OpenMP was too entrenched in the language extension space (and has since grown at least the potential of cilk like functionality), while more portable libraries (TBB for example) covered everything else.

I think it has been highly influential though.

Re:Composable multi-threaded parallelism in Julia by scott_s on Wednesday July 24, 2019 @09:32AM (#20515058)
Yes, Cilk has been enormously influential. I have personally cited it many times. But I always had the impression it was a little too early for its time, and was never picked up by the HPC community, hence my question.
Re:Composable multi-threaded parallelism in Julia by minxomat on Tuesday July 23, 2019 @09:10PM (#20511585)
Cilk maybe not, but TBB is just a library (or more accurately a toolbox of primitives), which integrates nicely with OpenMP: https://software.intel.com/en-us/node/506128
Re:Composable multi-threaded parallelism in Julia by krapht on Tuesday July 23, 2019 @07:30PM (#20511128)
The real gain is with MPI, anyway... shared memory is a trap. All the projects I've worked on have exploited parallelism through message passing, or a battle tested multithreaded linear algebra library.
Re:Composable multi-threaded parallelism in Julia by BubRoss on Tuesday July 23, 2019 @08:26PM (#20511383)
There are many techniques and calling any of them the one solution and all others a trap is extremely myopic. Shared memory is extremely useful for IPC and fork join parallelism.
Re:Composable multi-threaded parallelism in Julia by gpderetta on Wednesday July 24, 2019 @05:58AM (#20513642)
My understanding is that, at least in c/Fortran/c++ land common practice is openmp within a machine and MPI across machines. I've done some work of the sort but I'm far from an expert though.
Re:Composable multi-threaded parallelism in Julia by steev on Wednesday July 24, 2019 @06:40AM (#20513826)
You are correct.
Re:Composable multi-threaded parallelism in Julia by vmchale on Tuesday July 23, 2019 @09:41PM (#20511743)
> All the projects I've worked on have exploited parallelism through message passing

What? Lots of parallelism doesn't use message passing!

Re:Composable multi-threaded parallelism in Julia by seanmcdirmid on Wednesday July 24, 2019 @12:50AM (#20512439)
GPU is the way to go these days to get most parallelism, and it is definitely the shared memory variety. Message passing is the go to when parallelism needs to cross machine boundaries.
Re:Composable multi-threaded parallelism in Julia by steev on Wednesday July 24, 2019 @06:42AM (#20513835)
GPU parallelism is highly specialized and requires very specific workloads (e.g., many linear algebra workloads). GPUs are a bad choice for general parallelized tasks.
Re:Composable multi-threaded parallelism in Julia by seanmcdirmid on Wednesday July 24, 2019 @02:00PM (#20517835)
Yes, but for heavy numeric problems, GPUs are your best bet if you can make them work. The question is what is Julia being used for, I guess.
Re:Composable multi-threaded parallelism in Julia by scott_s on Wednesday July 24, 2019 @04:34PM (#20519363)
A quibble: it's not necessarily "heavy numeric" problems, but problems where the calculations involve extensive data-reuse. (Of which matrix operations are the most obvious.) The GPU is massively parallel, but the up-front cost of transferring data to the GPU is quite high.

Hence, in order for that up-front cost to be worth it, the algorithms run on the GPU need to re-use that data many times. If the algorithms running on the GPU don't make extensive reuse of the data sent to it, it would be faster to just do the calculation on the host CPU.

Re:Composable multi-threaded parallelism in Julia by marmaduke on Wednesday July 24, 2019 @02:39AM (#20512830)
MPI is the HPC horizontal scaling strategy, for when you need to go from 1 core to 500k.
Re:Composable multi-threaded parallelism in Julia by manigandham on Tuesday July 23, 2019 @07:08PM (#20511032)
You're missing C#/.NET which has had async/parallel programming constructs for a long time, and served as the model for await/async copied by many other languages.

It's gone through several design patterns from the original APM (async programming model) to EAP (event based pattern) to TPL (task parallel library) to the all purpose Task/ValueTask embedded into the language. It's very fast and efficient, and you can build your own scheduler too. Combined with hardware intrinsics in the latest .NET Core, it's very good for computational and server work.

I'm surprised Julia considers this such a big update but it does seem to be an overstatement to say this changes technical computing.

Re:Composable multi-threaded parallelism in Julia by StefanKarpinski on Wednesday July 24, 2019 @01:04AM (#20512490)
Julia has has the equivalent of async/await forever, except without needing to annotate anything with keywords—that’s just how I/O works. If you call a blocking function, it yields back into the scheduler. In Julia (as of 1.3), tasks are mapped onto multiple threads which run at the same time (in parallel) and threads that are idle can steal work efficiently. This is similar (as was said) to Cilk, TBB and Go. It is not the same as async/await in C#, which is concurrent but not parallel.

What is 100% new and does not exist in any other system is that the task scheduling is depth first (rather than breadth first), which is a much better order for doing compute-heavy workloads. This ability is new and was the culmination of an Intel research project, applied to Julia.

Re:Composable multi-threaded parallelism in Julia by gpderetta on Wednesday July 24, 2019 @06:07AM (#20513696)
Hum, isn't cilk-like work stealing depth first? Idle executors steal oldest ancestor and busy executors eagerly execute recursive calls while pushing parent in the local job stack?

Proof of optimality was in the early cilk papers in the '90s.

I'm sure the same algorithms made into Julia via Intel (which bought cilk in the early '00), but it is hardly new except in the 'everything old is new again'.

Also IIRC OpenMP supports (or at least allows) work stealing although at least GCC does not implement it yet.

Re:Composable multi-threaded parallelism in Julia by leiroigh on Wednesday July 24, 2019 @08:21AM (#20514422)
It's all about better L3 utilization. Cilk is good for using L1 and L2, i.e. caches that are core-local, and suboptimal for using L3, i.e. caches that are shared between cores.
Re:Composable multi-threaded parallelism in Julia by gpderetta on Wednesday July 24, 2019 @09:21AM (#20514965)
Can you expand on this or point me to a paper discussing this?
Re:Composable multi-threaded parallelism in Julia by ddragon on Wednesday July 24, 2019 @09:37AM (#20515107)
In the presentation posted here there was a paper citation that compared in terms of cache the model used (parallel depth first scheduling) over work stealing, but I didn't have time to read it yet.

https://www.cs.cmu.edu/%7Echensm/papers/ConstructiveCacheSha...

Re:Composable multi-threaded parallelism in Julia by gpderetta on Wednesday July 24, 2019 @10:10AM (#20515438)
Can't manage to download the file though my flimsy mobile connection, but I'm starting to understand the difference.
Re:Composable multi-threaded parallelism in Julia by dwohnitmok on Wednesday July 24, 2019 @01:25AM (#20512555)
What do you mean by depth first vs breadth first? Naively I would assume task scheduling necessarily to be depth first in some sense because you have to evaluate your tasks' dependencies first.
Re:Composable multi-threaded parallelism in Julia by StefanKarpinski on Wednesday July 24, 2019 @01:31AM (#20512578)
Consider a machine with N cores running a program which spawns N parallel tasks, each of which in turn spawns N parallel tasks. Which subtasks do the cores work on initially? If it's the first subtask of each top-level task, that's breadth-first scheduling. If it's all N subtasks of the first top-level task, that's depth-first scheduling. The latter is better for high-performance computing because it tends to be the lower level libraries that are really carefully tuned to make optimal use of the machine (think BLAS/FTT/parallel sum/prefix sum). Previously it was unknown how to implement this kind of scheduling efficiently. See this talk by Kiran Pamnany for more details:

https://www.youtube.com/watch?v=YdiZa0Y3F3c

Re:Composable multi-threaded parallelism in Julia by dwohnitmok on Wednesday July 24, 2019 @01:57AM (#20512687)
Ah I see what you mean! I really hate to pile on with the Haskell observation but the 1995 paper by Blelloch that is mentioned in that talk is exactly the heart of GHC's data parallelism as well (under the name nested data parallelism).

See slide 8 here: https://www.microsoft.com/en-us/research/wp-content/uploads/...

Later versions of Blelloch's language are referred to in other parallel Haskell papers.

FWIW I think this is nonetheless fantastic news for Julia! It's certainly poised to do great work in areas that I doubt will get any Haskell traction anytime soon (if ever) for good reasons.

EDIT: Interesting, I think Julia is taking a coarser grained approach here that breaks down a bit for irregularly balanced execution trees, but relies less on fusion (i.e. doesn't use fusion at all) which is nice. I'm curious to see how this particular implementation of the "depth first" idea goes!

EDIT EDIT: Actually I'm not sure how much fusion is necessary for GHC's approach... Time to investigate more closely. Also call out to anyone more familiar with Data Parallel Haskell to chime in. I'm getting out of my depth.

Re:Composable multi-threaded parallelism in Julia by StefanKarpinski on Thursday July 25, 2019 @12:55AM (#20522667)
I'm not surprised that Haskell supports this kind of parallelism, although I wasn't aware of it previously. After all, if you're going to the trouble of being that pure, why not be parallel?
Re:Composable multi-threaded parallelism in Julia by manigandham on Wednesday July 24, 2019 @02:14AM (#20512741)
Isn't a blocking function, by definition, something that blocks and doesn't yield? How could the language know to automatically yield on something without annotations?

> "async/await in C#, which is concurrent but not parallel"

C# is multithreaded. Things can only be parallel if you have 2 separate paths of execution that don't depend on each other or any serial order, but you can also kick off millions of individual tasks in a single function and await them all too. These tasks are all scheduled onto threads in a managed threadpool that also share work and run at the same time. I fail to see how this is any different or less capable than the others you mentioned.

Re:Composable multi-threaded parallelism in Julia by StefanKarpinski on Wednesday July 24, 2019 @02:34AM (#20512811)
C# has threads but async/await does not use them. If you think that `async` in C# does the same thing as `@spawn` in Julia and `go` in Go, you are mistaken. It does not. There is also an `@async` macro in Julia that does what the `async` keyword in C# does (which, again, does not involve threads).

https://stackoverflow.com/questions/37419572/if-async-await-...

https://blog.stephencleary.com/2013/11/there-is-no-thread.ht...

https://blogs.msdn.microsoft.com/benwilli/2015/09/10/tasks-a...

Re:Composable multi-threaded parallelism in Julia by manigandham on Wednesday July 24, 2019 @03:05AM (#20512927)
I'm very familiar with C# and I'm not talking about threads, only that multi-threading is a basic requirement and C# has a threadpool running threads in parallel.

I said that C# also uses Tasks which are scheduled onto these threads, which is what you said Julia does, so it's the same. C# can also start new threads just as easily, or use channels like Go with the TPL/Dataflow, System.Threading.Channels, actor frameworks, Reactive Extensions, or just chaining tasks together. Other than the depth-first algorithm, it seems like C# has the same capabilities as Julia and the others, if not more, and is much more "mainstream".

Can you explain how blocking functions are automatically yielded without keywords though? I cant find any documentation on this that doesnt mention the @async macro.

Re:Composable multi-threaded parallelism in Julia by opportune on Tuesday July 23, 2019 @07:38PM (#20511175)
I really dislike using Tasks over threads due to the reusability issues. Specifically that Tasks are not reusable and threads are. It makes parallel computational work a headache, because you need to implement the reusability in a higher scope than tasks, then make an effort to prevent race-conditions, double checkouts, etc.

Tasks are really meant for responsive computing, not proactive computing (yes, even TPL and Dataflow), and thus I don't think they are well suited to parallelized computation in areas like e.g. simulation.

Re:Composable multi-threaded parallelism in Julia by minxomat on Tuesday July 23, 2019 @09:05PM (#20511560)
When a program is composed as a Dataflow pipeline, you don't handle tasks at all (unless you want to). I'm not sure what reusability issues you're referring to. Dataflow is very applicable to high CPU-throughput (i.e. efficient) pipelines. Concurrent by default, parallel on-demand. In practice, any I/O in my pipelines takes place in singleton consumers at the end of complex, highly-parallel, CPU-intensive code.

C# code that uses Tasks and C# programs built on Dataflow are very different. The latter benefits you most when you commit entirely to that paradigm.

If you want to get more low-level, low-overhead (for i.e. simulations), the same thing applies to things like Threading Building Blocks[1] in C++. I'd even argue that TBB is one of the best applications of this theory, going so far as to ship with dedicated tooling for the whole lifecycle of designing to implementing to profiling task- and graph-parallel programs [2]. Furthermore, it works well with other HPC libraries. Here [3] is an example of mixing it with OpenMP.

In summary, both Dataflow and TBB (et al) can readily be used to create CPU-intensive, proactive computing pipelines today. Even though they're "just" fancy Task schedulers, which are in turn "just" fancy thread multiplexers.

[1] - https://www.threadingbuildingblocks.org/tutorial-intel-tbb-f...

[2] - https://www.youtube.com/watch?v=9bBqFW5hnVM

[3] - https://software.intel.com/en-us/node/506128

Re:Composable multi-threaded parallelism in Julia by manigandham on Tuesday July 23, 2019 @08:58PM (#20511519)
What do you mean by reusable exactly? And how does proactive computing differ? Do you have an example you can share?
Re:Composable multi-threaded parallelism in Julia by opportune on Tuesday July 23, 2019 @10:20PM (#20511925)
Reusable as in, I can create a datastructure in a thread, do some computation, yield control from the thread (wait for something else to tell it to go again), then come back to the thread with the same datastructure and keep going. With Tasks, you are supposed to let tasks complete rather than let them pause/sync so anything you declare locally is lost when you want to restart it. The workaround is to declare things in a higher scope and pass them into tasks as they are reran - this makes tasks not suited to things where you want to persist data, since tasks are opinionated in that they are only meant to contain logic, not state, so you have to add your own external logic to manage the allocation of state to the tasks that you keep recreating

This trait of tasks makes sense when writing things like web servers because it prevents developers from shooting themselves in the foot by writing something that isn't stateless.

By proactive computing, I mean some program that always has control of the entire execution graph. For example, a simulation may initialize a bunch of datastructures, separate some of them into threads, run the threads, wait for all of them to complete x ticks, do some synchronization or measurement of the total system, then continue y times, and exit.

Re:Composable multi-threaded parallelism in Julia by DNF2 on Wednesday July 24, 2019 @03:37AM (#20513058)
What would be the purpose of yielding control from the thread and tell it to wait, rather than just let it run to completion?
Re:Composable multi-threaded parallelism in Julia by ska on Wednesday July 24, 2019 @01:44PM (#20517643)
Sometimes you don't know where you want to spend your CPU budget until you have more information.
Re:Composable multi-threaded parallelism in Julia by DNF2 on Wednesday July 24, 2019 @02:02PM (#20517864)
Maybe I misunderstand you, but telling the thread to halt is surely a waste of those resources?
Re:Composable multi-threaded parallelism in Julia by opportune on Wednesday July 24, 2019 @04:22PM (#20519250)
Because sometimes you need to sync the entire program state, or some subset of the state, to make measurements or to let disparate parts of the system interact
Re:Composable multi-threaded parallelism in Julia by ska on Tuesday July 23, 2019 @09:08PM (#20511575)
I’m not certain an overstatement. I’m not convinced either. As you note these ideas are old (they mostly predate C# and .NET by decades). On the other hand, to a first order approximation, C# has made zero impact in this area. There are a bunch of reasons, but that’s the way it is.

Fair or not, Julia does seem to have the potential to be the first really interesting shift in this area in ages. Doesn’t mean it will get there, but there is interest.

Re:Composable multi-threaded parallelism in Julia by manigandham on Tuesday July 23, 2019 @10:43PM (#20512015)
I was pointing out another very mainstream language (even more than Go and far more than Erlang) that has the same abilities.

What do you mean by impact/shift exactly? I guess I'm not understanding what's suddenly going to change now since, as you say, these ideas are old and implemented several times before.

Re:Composable multi-threaded parallelism in Julia by ska on Tuesday July 23, 2019 @11:42PM (#20512232)
What I mean is that C# has not been taken up for heavy numeric work in a significant way.

Julia, for good or ill, seems to have some potential to be.

Re:Composable multi-threaded parallelism in Julia by seanmcdirmid on Wednesday July 24, 2019 @12:53AM (#20512451)
Task concurrency is probably not a great idea for heavy numeric work anyways, right? I’m scratching my head a bit about what the use case for this is in Julia given that there are much better ways of doing parallelism already.
Re:Composable multi-threaded parallelism in Julia by DNF2 on Wednesday July 24, 2019 @03:33AM (#20513043)
Which ways are those?
Re:Composable multi-threaded parallelism in Julia by seanmcdirmid on Wednesday July 24, 2019 @07:58AM (#20514255)
Data parallelism mostly.
Re:Composable multi-threaded parallelism in Julia by DNF2 on Wednesday July 24, 2019 @02:04PM (#20517884)
We're not talking about concurrency, but actual parallelism.

Anyway, if by data parallelism you mean simd, then that is already available and widely used in Julia. Multithreading comes on top of that.

Re:Composable multi-threaded parallelism in Julia by jakear on Tuesday July 23, 2019 @05:40PM (#20510468)
The interface does look a lot like Cilk, which is a definite plus as that is an absolute pleasure to use.

This however offers a lot more configurability than Cilk (or at least more accessible configuration). Whether that’s a curse or blessing... I guess we’ll find out! :)

Also, have you looked into implementing Cilk-style reducers at all? [0]

[0]: https://www.cilkplus.org/docs/doxygen/include-dir/group___re...

Re:Composable multi-threaded parallelism in Julia by leiroigh on Tuesday July 23, 2019 @08:41PM (#20511436)
Big difference is that Cilk appears to typically synchronize on function return, while julia needs an explicit wait/fetch (there is also a @sync macro). That is, spawn/wait can be matched from the AST in cilk, while julia demands that the user communicates and stores a reference to the started task for later waiting.

It is easy to forget to wait on a task, or even lose reference to it. The current scheduler will typically execute this task quickly, even if nobody ever waits on it; until load changes and you have races everywhere. There are currently no warnings comparable to Python's "RuntimeWarning: coroutine foo was never awaited".

Re:Composable multi-threaded parallelism in Julia by jakear on Wednesday July 24, 2019 @01:31AM (#20512581)
Cilk does indeed sync on function return. You can also manually call 'cilk_sync'. I do think that Cilk’s approach is better (more in line with “make error states unrepresentable”, which I’m a big fan of), but Julia’s approach seems to be more in line with their overall goal of giving the programmer as much control as possible. Not sure if that’s a good thing or not, but as said above... we’ll find out soon!
Re:Composable multi-threaded parallelism in Julia by gpderetta on Wednesday July 24, 2019 @07:22AM (#20514027)
Affine types to represent futures would help here.
Re:Composable multi-threaded parallelism in Julia by Arnavion on Tuesday July 23, 2019 @05:25PM (#20510367)
>The only mainstream languages with this kind of composable parallelism are Go and Erlang, both of which target writing servers, rather than high-performance computing, and which therefore optimize for I/O throughput rather than CPU throughput.

Rust, while perhaps not as mainstream and not necessarily targeting scientific computing users, has data-bound parallelization like this via the rayon library.

Re:Composable multi-threaded parallelism in Julia by oconnor663 on Tuesday July 23, 2019 @06:04PM (#20510637)
Which indeed was named after Cilk.
Re:Composable multi-threaded parallelism in Julia by StreamBright on Wednesday July 24, 2019 @02:58AM (#20512905)
> The only mainstream languages with this kind of composable parallelism are Go and Erlang

I think there are a few more of those languages. AFAIK Clojure and Rust should be added to the list.

Re:Composable multi-threaded parallelism in Julia by vmchale on Tuesday July 23, 2019 @09:39PM (#20511732)
> The only mainstream languages with this kind of composable parallelism are Go and Erlang

Concurrency? Go is not good at parallelism, compared to, say, Haskell.

Re:Composable multi-threaded parallelism in Julia by bakery2k on Wednesday July 24, 2019 @12:34AM (#20512386)
What's wrong with parallelism in Go?
Re:Composable multi-threaded parallelism in Julia by radiospiel on Wednesday July 24, 2019 @05:06AM (#20513415)
I have something in the works which is very similar - but is language agnostic. Pro: no need to switch to another language; Con: not high performance.

We are using this in production for now over 1 year, and it helps tremendously. We are currently only supporting a ruby client, but other languages should be more or less easy to bring into the mix. A wider release is planned for later this year - feel free to ask me anything via email!

Re:Composable multi-threaded parallelism in Julia by marmaduke on Wednesday July 24, 2019 @02:40AM (#20512838)
Will this be worked to scale to multiple machines?
Re:Composable multi-threaded parallelism in Julia by StefanKarpinski on Wednesday July 24, 2019 @02:52AM (#20512887)
Julia has supported distributed compute forever. Just give it a machine file and you have an instant fully connected cluster.
Re:Composable multi-threaded parallelism in Julia by holy_city on Tuesday July 23, 2019 @07:36PM (#20511168)
MATLAB has had this for years. But it costs $1,000 on top of the existing license cost. And it's lumped together with their GPGPU/cluster tools.
Re:Composable multi-threaded parallelism in Julia by DNF2 on Wednesday July 24, 2019 @03:43AM (#20513079)
If you're talking about the Parallel Computing Toolbox (PCT), then, no, you do not get access to multithreading through that, only multiprocessing and GPU processing. I recently considered buying the PCT, and this is one of the main reasons I probably won't.

The only type of multithreading in Matlab is the type that is built into the core language, and you don't get any control over that.

Finally, the claim to originality here isn't just the introduction of multithreading (which isn't even new in Julia!), but the particular threading model and scheduler, which lends itself particularly well to composable multithreading.

Re:Composable multi-threaded parallelism in Julia by mruts on Tuesday July 23, 2019 @06:30PM (#20510816)
Scala futures seem to offer all of this functionality as well, no? And you can do all the regular monad stuff on them as well, which is super nice.