Concurrency is not Parallelism (it's better) - A talk by Rob Pike
concur.rspace.googlecode.com
concur.rspace.googlecode.com
Of course, concurrency is not the end of things. Deterministic parallelism is a beautiful model for making things faster, easily. So you need that in your language somehow too.
Edit: there's a cite for Bob Harper on this, http://existentialtype.wordpress.com/2011/03/17/parallelism-... , which was a bit later than Simon's post.
In particular, the Kilim library for Java uses "microthreads" (similar to goroutines) plus a linear ownership transfer system such that only one microthread owns a given object/object graph at a time, preventing concurrent state mutation while still providing mutable state. Sending an object from one Kilim task to another transfers ownership, and thus messages become the mechanism by which state is isolated at the process level.
Mutable state can be safe too. You just need the proper abstractions.
Immutable state gives you compile-time-safety. I think when people say "shared mutable state is unsafe", at least some of them are referring to compile-time safety. If it compiles, these kinds of concurrency-related bugs are impossible.
"Parallelism should not be confused with concurrency. Parallelism is about efficiency, not semantics; the meaning of a program is independent of whether it is executed in parallel or not. Concurrency is about composition, not efficiency; the meaning of a concurrent program is very weakly specified so that one may compose it with other programs without altering its meaning. This distinction, and the formulation of it given here, was pioneered by Blelloch (1990). The concept of a cost semantics and the idea of a provably efficient implementation are derived from Blelloch and Greiner (1995, 1996a)."
39.5 Notes, Practical Foundations of Programming Languages, Version 1.30 Revised 03.15.2012
Concurrency is a programming language issue, parallelism is a resource allocation issue.
EDIT: Well, this appears to be stated pretty clearly in the presentation, but I only got the presentation working after trying it for the 3rd time (in the 3rd browser).
We need more cute illustrations of CS topics.
I personally am good with pictorials and the do/fail iteration styles of learning. Text is passable, but I am usually translating it to pictures in my head. There have been times where I have gotten more out of one crappy but representative picture than I have out of an hour lecture. Good pictures that engage the viewer are even better. In this case I was easily able to imagine the gophers walking along doing their tasks, and just "seeing" the flow because the picture was pretty representative. I could have gotten the same message from boxes and arrows, but not as quickly I think.
So why should we have more good diagrams? Because it would help more people of a certain type learn to program easier.
So for a good lesson in concurrency and parallelism, play Dwarf Fortress.
I hope that's a typo. A thread is blocked when a goroutine blocks would exhaust the worker thread pool pretty fast. Can an GO expert clarify on that?
You can have tens of thousands of Goroutines without any problems.
I have seen this same idea ("goroutines are very light and multiplexed into OS threads, don't worry about it") stated often, but I do not understand it, and I have not found any place where the implementation of this is actually discussed, do you have any pointers?
For a background in the CSP languages have a browse of Russ Cox's http://swtch.com/~rsc/thread/ The reference [4] to Squeak is broken, it's now at http://research.microsoft.com/pubs/67508/squeak.pdf and well worth a read.
For the general case, not Go specific, there's a scheduler that tracks what processes (in the CSP sense, e.g. goroutine) are waiting on what channels. Whenever a channel becomes ready, e.g. something is available to read from it, one of the processes waiting to read from it is non-deterministically (that's important) chosen and control (the CPU's program counter, still in user-space) jumps to where it returns from the `read'. It then has the CPU all to itself until it gives control back to the scheduler by needing another particular channel-state. I'm omitting sleeping, etc., for simplicity. The switching of control is all in user-space so quite lightweight.
I understand what you meant, but it's kind of confusing to use the same term for different things within the same slide while claiming they are different.
They are "cooperatively scheduled concurrent execution sharing memory".
That being said, I prefer my goroutines to be cooperatively scheduled.
This is not the case with many other (single-threaded) systems built exclusively around a god-loop that schedules coroutines. One coroutine making a blocking system call gums up the whole works.
More relevantly - definitely going to come up with more stories/silly pictures for presentations in the future. It channels the memory technique of making ridiculous associations that actually stick.
It seems the Clojure way is to use something like Aleph (https://github.com/ztellman/aleph, http://blip.tv/clojure/zach-tellman-aleph-a-framework-for-as...), which is a library that implements channels like Go; however, Go's channels are first-class constructs built into the language.
Does Google foresee a future entirely built in Go, the same way NeXT expected the world to evolve towards Objective-C?
Eventually, sure, why not?
Still you don't need your whole OS to be in pure Go to take advantage of Go's features, most Go systems are purely in Go as the stdlib is quite complete, but even then there is no issue linking with (most) existing C code if you need to (C code that does its own threading stuff obviously is more problematic).
It looks like we are headed toward a future with many more languages, not fewer.
If there are equivalent ways of designing for concurrency in Java or C# (or those ways are added to the language in the future), then you may be able to restructure existing Java and C# code bases to take advantage of this approach.
If you have 20 million lines of Cobol transaction processing code and there's no practical way of migrating your code base to use this methodology, then your 20 million lines of Cobol will keep running the same way they always have.
Unless I'm missing a point you're trying to make (certainly possible) there's no reason to think that this is an all or nothing approach.
The upcoming 4.5 release fixes some of the ugly.
It may be a long time but there will someday be a world not built on C or C++. Probably within my lifetime. (Probably.)
putting only one manual per cart is SISD vs. putting several manuals per cart which is SIMD
Also his example (moving manuals) is really example of parallelism and not concurrency. He has one large problem, which is decomposed to two smaller problems. Not much different from multiplying two large vectors.
The real example of concurrency would be: librarians handling books returned to the library. They don't know how many books will be returned and when - i.e. very similar to web server handling HTTP requests.
Concurrency
property of systems in which several computational processes are executing at the same time, and potentially interacting with each other
Parallelism
computation in which many calculations are carried out simultaneously, operating on the principle that large problems can often be divided into smaller ones, which are then solved concurrently (i.e. "in parallel")
But the presentation is about concurrency and parallelism not being the same thing, and more concurrency not necessarily leading to more parallelism.
> Don't make excuses for your language.
There's no excuse made.
> Just solve the problem!
There's no problem to solve. If you're asked to count from 1 to 100, you can't parallelize it: it's a purely sequential task, each step has a hard dependency on the previous step. So there is no possible parallelism.
But it is possible to do something else at the same time, or to have one process handling the counting and sending the current count to an other process printing it. That's concurrency: you've got two things running at the same time.
But the reason almost nobody uses any of the general forms of this concurrency (coroutines, fibers) is because the general case of this is as useless as it is easy to do. For instance there are plenty of C coroutine libraries (including Russ' libtask) and they work fine. The reason nobody uses them is the because the situations where this is called for are precious few.
The other day on reddit Ian of gccgo even butted into a conversation about 1:1 threads vs m:n threads, but could not muster up an answer as to what conditions m:n threads (ala goroutines) would be called for. Simultaneous execution (threads for example) was always the hard part and any talk about concurrency that isn't about simultaneous execution is just tilting at windmills.
For instance in golang the only support the language has for simultaneous execution is a threadsafe queue -- that's all. And the runtime libraries only have variations on mutex that you even have to manually create locks and manually remember to unlock them. This is extremely weak sauce for a 'concurrent' language.