Live data from Hacker News

Ask HN: On Rob Pike's Concurrency is not Parallelism?

news.ycombinator.com

21–30 of 71 posts

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#21
post #18

Take a look at lthread: https://github.com/halayli/lthread lthread supports concurrency and parallelism using pthreads. Each lthread scheduler runs its own lthreads concurrently, or better said, one at a time. But from an observer's perspective they look like they are running in parallel. Now if you create 2 pthreads on a 2 core machine and each runs an lthread scheduler then you have true parallelism because you can…

Just noticed the license changed to BSD! I had not realised - will definitely need to give it another look as I may be able to make use of it now. Awesome.

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#22
post #9

Earlier quoted context omitted.

I don't agree with that; task parallelism is easier than data parallelism in an actor/CSP-based system, but both have their place. Take something like x264 -- task parallelism will not help it, unless you're encoding multiple videos at one time. But data parallelism (SIMD, in particular) is the reason it's the fastest encoder around.

In general, task paralellism can model anything data parallelism can and given "a sufficiently smart compiler" you can end up with the same result. This is an informal corollary of Needham's Duality (which is itself informal, so make of it what you will). Our current hardware tends to offer great data parallelism for homogenous task queues and task parallelism for heterogenous task queues. Given that, we task paralle…

For a "sufficiently smart compiler" you mean autovectorization. That's a hard problem.

I've mentioned before that I don't think SIMD is going away anytime soon. It has so many upsides (cache locality, simple implementation in hardware due to the single-instruction nature of it) that I think designs that don't take advantage of it will always be at a disadvantage for the foreseeable future.

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#23
post #18

Take a look at lthread: https://github.com/halayli/lthread lthread supports concurrency and parallelism using pthreads. Each lthread scheduler runs its own lthreads concurrently, or better said, one at a time. But from an observer's perspective they look like they are running in parallel. Now if you create 2 pthreads on a 2 core machine and each runs an lthread scheduler then you have true parallelism because you can…

Just noticed the license changed to BSD! I had not realised - will definitely need to give it another look as I may be able to make use of it now. Awesome.

Yup I changed it couple months ago :)

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#24
post #9

Earlier quoted context omitted.

I don't agree with that; task parallelism is easier than data parallelism in an actor/CSP-based system, but both have their place. Take something like x264 -- task parallelism will not help it, unless you're encoding multiple videos at one time. But data parallelism (SIMD, in particular) is the reason it's the fastest encoder around.

x264 gets equal use from threads per-frame as it does SIMD per-pixel. There's a pretty much linear speed increase for each new thread, even.

Interesting, I didn't know that video encoding could be parallelized per-frame in that way. That's really cool; I stand corrected.

Still, I think it's clear that an x264 with N threads per frame with no per-pixel SIMD would lose to the current x264 with N threads per frame. The key is that x264 is making good use of task parallelism and data parallelism.

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#25
post #20

Earlier quoted context omitted.

Go scales quite well across multiple cores iff you decompose the problem in a way that's amenable to Go's strategy. Same with Erlang. No one is making "excuses". It's important to understand these problems. Not understanding concurrency, parallelism, their relationship, and Amdahl's Law is what has Node.js in such trouble right now.

Trouble? Node.js has linear speedup over multiple cores for web servers. See http://nodejs.org/docs/v0.8.4/api/cluster.html for more info.

It's parallel in the same sense that any POSIX program is: Node pays a higher cost than real parallel VMs in serialization across IPC boundaries, not being able to take advantage of atomic CPU operations on shared data structures, etc. At least it did last time I looked. Maybe they're doing some shm-style magic/semaphore stuff now. Still going to pay the context switch cost.

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#26
post #7
post #4

Parallelism is when you run your program on multiple processors. Semantics of your program does not change whether you run it on single processor or multiple processors. Concurrency is when you write your program using multiple threads. Your program looks and means vastly different if you use threads. You use concurrency not for performance gain, but for clarity of your program. You use parallelism for performance ga…

That can't be right. Threads don't improve the clarity of most programs; they're notoriously unclear.

On the contrary, I think proper concurrency constructs, including threads, do improve the clarity of programs. Part of the problem in reasoning about threads is a lack of useful primitives. Multithreaded programming in Java? For me, at least, it's tough. In Erlang? Trivial. In Clojure, if you're willing to deal with the slowness of the STM, it can be beautifully simple.

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#27
post #25
post #20

Earlier quoted context omitted.

Trouble? Node.js has linear speedup over multiple cores for web servers. See http://nodejs.org/docs/v0.8.4/api/cluster.html for more info.

It's parallel in the same sense that any POSIX program is: Node pays a higher cost than real parallel VMs in serialization across IPC boundaries, not being able to take advantage of atomic CPU operations on shared data structures, etc. At least it did last time I looked. Maybe they're doing some shm-style magic/semaphore stuff now. Still going to pay the context switch cost.

it's all serialization - but that's not a bottleneck for most web servers. i'd love to hear your context-switching free multicore solution.

this is the sanest and most pragmatic way server a web server from multiple threads

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#28
post #27
post #25

Earlier quoted context omitted.

It's parallel in the same sense that any POSIX program is: Node pays a higher cost than real parallel VMs in serialization across IPC boundaries, not being able to take advantage of atomic CPU operations on shared data structures, etc. At least it did last time I looked. Maybe they're doing some shm-style magic/semaphore stuff now. Still going to pay the context switch cost.

it's all serialization - but that's not a bottleneck for most web servers. i'd love to hear your context-switching free multicore solution. this is the sanest and most pragmatic way server a web server from multiple threads

Threads and processes both require a context switch, but on posix systems the thread switch is considerably less expensive. Why? Mainly because the process switch involves changing the VM address space, which means a TLB shootdown: all that hard-earned cache has to be fetched from DRAM again. You also pay a higher cost in synchronization: every message shared between processes requires crossing the kernel boundary. So not only do you have a higher memory use for shared structures and higher CPU costs for serialization, but more cache churn and context switching.

it's all serialization - but that's not a bottleneck for most web servers.

I disagree, especially for a format like JSON. In fact, every web app server I've dug into spends a significant amount of time on parsing and unparsing responses. You certainly aren't going to be doing computationally expensive tasks in Node, so messaging performance is paramount.

i'd love to hear your context-switching free multicore solution.

I claimed no such thing: only that multiprocess IPC is more expensive. Modulo syscalls, I think your best bet is gonna be n-1 threads with processor affinities taking advantage of cas/memory fence capabilities on modern hardware.

this is the sanest and most pragmatic way server a web server from multiple threads

What is this I can't even.

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#29
post #26
post #7

Earlier quoted context omitted.

That can't be right. Threads don't improve the clarity of most programs; they're notoriously unclear.

On the contrary, I think proper concurrency constructs, including threads, do improve the clarity of programs. Part of the problem in reasoning about threads is a lack of useful primitives. Multithreaded programming in Java? For me, at least, it's tough . In Erlang? Trivial. In Clojure, if you're willing to deal with the slowness of the STM, it can be beautifully simple.

Erlang and Clojure don't have threads in the common meaning of the term (http://en.wikipedia.org/wiki/Thread_(computing)). They are reactions against programming with threads.

You can expand the term "thread" to mean "concurrency in general" but even then it isn't true that the main purpose of writing concurrent code is clarity. When people say "look at this concurrent program I wrote" they rarely [1] say "look at how well the code expresses the problem". What they overwhelmingly say is "look at this benchmark".

[1] Joe Armstrong talks about how Erlang lets you represent processes more like they happen in the real world. But that's a niche view. Most people think about concurrency as a platform issue, where the platform is multicore hardware or distributed systems, and otherwise wouldn't bother with it.

Re: Ask HN: On Rob Pike's Concurrency is not Parallelism?

#30
post #27
post #25

Earlier quoted context omitted.

It's parallel in the same sense that any POSIX program is: Node pays a higher cost than real parallel VMs in serialization across IPC boundaries, not being able to take advantage of atomic CPU operations on shared data structures, etc. At least it did last time I looked. Maybe they're doing some shm-style magic/semaphore stuff now. Still going to pay the context switch cost.

it's all serialization - but that's not a bottleneck for most web servers. i'd love to hear your context-switching free multicore solution. this is the sanest and most pragmatic way server a web server from multiple threads

Don't believe me? Try it:

Node.js: https://gist.github.com/3200829

Clojure: https://gist.github.com/3200862

Note that I picked the really small messages here--integers, to give node the best possible serialization advantage.

    $ time node cluster.js 
    Finished with 10000000

    real 3m30.652s
    user 3m17.180s
    sys	 1m16.113s
Note the high sys time: that's IPC. Node also uses only 75% of each core. Why?

    $ pidstat -w | grep node
    11:47:47 AM     25258     48.22      2.11  node
    11:47:47 AM     25260     48.34      1.99  node
96 context switches per second.

Compare that to a multithreaded Clojure program which uses a LinkedTransferQueue--which eats 97% of each core easily. Note that the times here include ~3 seconds of compilation and jvm startup.

    $ time lein2 run queue
    10000000
    "Elapsed time: 55696.274802 msecs"

    real 0m58.540s
    user 1m16.733s
    sys	 0m6.436s
Why is this version over 3 times faster? Partly because it requires only 4 context switches per second.

    $ pidstat -tw -p 26537
    Linux 3.2.0-3-amd64 (azimuth) 	07/29/2012 	_x86_64_	(2 CPU)
    
    11:52:03 AM      TGID       TID   cswch/s nvcswch/s  Command
    11:52:03 AM     26537         -      0.00      0.00  java
    11:52:03 AM         -     26540      0.01      0.00  |__java
    11:52:03 AM         -     26541      0.01      0.00  |__java
    11:52:03 AM         -     26544      0.01      0.00  |__java
    11:52:03 AM         -     26549      0.01      0.00  |__java
    11:52:03 AM         -     26551      0.01      0.00  |__java
    11:52:03 AM         -     26552      2.16      4.26  |__java
    11:52:03 AM         -     26553      2.10      4.33  |__java
And queues are WAY slower than compare-and-set, which involves basically no context switching:

    $ time lein2 run atom
    10000000
    "Elapsed time: 969.599545 msecs"

    real 0m3.925s
    user 0m5.944s
    sys	 0m0.252s

    $ pidstat -tw -p 26717
    Linux 3.2.0-3-amd64 (azimuth) 	07/29/2012 	_x86_64_	(2 CPU)

    11:54:49 AM      TGID       TID   cswch/s nvcswch/s  Command
    11:54:49 AM     26717         -      0.00      0.00  java
    11:54:49 AM         -     26720      0.00      0.01  |__java
    11:54:49 AM         -     26728      0.01      0.00  |__java
    11:54:49 AM         -     26731      0.00      0.02  |__java
    11:54:49 AM         -     26732      0.00      0.01  |__java
 
TL;DR: node.js IPC is not a replacement for a real parallel VM. It allows you to solve a particular class of parallel problems (namely, those which require relatively infrequent communication) on multiple cores, but shared state is basically impossible and message passing is slow. It's a suitable tool for problems which are largely independent and where you can defer the problem of shared state to some other component, e.g. a database. Node is great for stateless web heads, but is in no way a high-performance parallel environment.
Post reply on HN