3 ms·
I think I finally figured it out recently. Concurrency is an I/O parallelism technique. One core can make 10,000 TCP connections at the same time thanks to asy
by dragontamer 5y ago
I think I finally figured it out recently.
Concurrency is an I/O parallelism technique. One core can make 10,000 TCP connections at the same time thanks to async, golang lightweight threads and whatnot.
This is useful because many I/O operations are high latency. A TCP connection, like HTTPS, takes high latency but the I/O device supports many operations.
-------
If you are I/O latency bound, you use concurrency to increase performance. Even with one CPU, concurrency or I/O parallelism helps a lot.
But if you are CPU bound, you need to use totally different techniques (parallel processing)
- paskozdilar 5y agoYou're on a right track - the most useful application of concurrency nowdays is I/O, because of the order-of-magnitude larger latency than CPU. However, concurrency is much more than IO. Concurrency can be best defined as a lack of ordering of computation. For example, you want to compute A, B, C and their values are independent of each other, the order you compute them does not matter - that is concurrency. If your language has means of expressing "compute these things, i dont care about the order", then your language supports concurrency. I suggest reading Communicating Sequential Processes by Tony Hoare. It is a very influential work on concurrency - and the proof of its influence is the design of the Go programming language.
- pengaru 5y agoCoroutines are a form of concurrency, and they may be executed in parallel if scheduled on separate cores/threads, but usually are just cooperatively scheduled serially. Concurrency is not an IO-specific concept.
- dragontamer 5y agoThe issue is that splitting up work into different blocks wrecks your L1 cache and locality of data. So if your code is: A(data) B(data) C(data) Doing A(data1), B(data1), C(data1) then A(data2), B(data2), C(data2) is much much faster than A(data1), A(data2), B(data1), B(data2), C(data1), C(data2). In most cases anyway (assuming data1 and data2 have a portion that fits somewhere in the cache hierarchy). So even if you are doing parallel execution, it ends up being a lot slower than sequential. -------- The goal of parallel processing is to actually get faster in terms of CPU time. Just grabbing concurrency techniques can be counterproductive.
- Jtsummers 5y agoThe current mainstream distinction seems to be: Parallelism - actually running (or intended to run) in parallel. A lot of computational work is like this. Concurrency - may run in parallel, but is about design as much, if not more, than execution. Concurrency is a way (in the current mainstream sense) to decompose a program into multiple "processes" (generic sense) much like we decompose programs into functions, procedures, and objects in other languages. I think it was Rob Pike's talk "Concurrency is not parallelism" which pushed this distinction further into the mainstream. https://go.dev/blog/waza-talk https://go.dev/blog/waza-talk - Concurrency is not parallelsim, Rob Pike Go, Erlang (later Elixir), and Clojure in particular seem to have pushed the idea of using concurrency (above sense) in the design of programs into the mainstream. Specifically bringing concurrency into "the small". Concurrency is an innate quality of networked programs, but within a program people often write sequential (non-concurrent) code and only add concurrency elements to access parallelism for performance (vice adding them because they clarify the code or its design). But many problems are neatly decomposed into well-performing concurrent designs that may get a performance boost if you have multiple cores available, but it isn't (strictly) the point of using concurrency.