liveBook · Manning

Parallelism

As explained in 100 Go Mistakes and How to Avoid Them

Parallel execution is the simultaneous execution of multiple instances of a task, typically on separate processing cores.

A common mistake is to treat concurrency and parallelism as synonyms. Parallelism means executing the same task multiple times at once; concurrency describes how work is structured into independently progressing parts. Duplicating both a waiter and a coffee machine serves orders in parallel. Splitting order-taking from coffee preparation changes the workflow, but does not by itself duplicate the task. section 8.1

In Go, goroutines make parallel work possible, but launching more of them does not guarantee a speedup. The runtime schedules goroutines onto OS threads, while CPU cores execute threads. For CPU-bound work, keep the number of active goroutines near GOMAXPROCS rather than assuming every small task deserves one. section 8.2.1 section 8.7

When parallel merge sort gets slower

A first attempt starts a goroutine for each half at every recursive split, waits for both halves, then merges them. On the reported benchmark, that version took 17.53 seconds per operation versus 2.28 seconds for sequential merge sort: tiny sublists did not justify the goroutine overhead. A revised version sorts sublists of 2,048 elements or fewer sequentially and starts goroutines only above that threshold; it took 1.31 seconds per operation. The threshold is an example to benchmark, not a universal setting. section 8.2.2

Benchmark_sequentialMergesort-4       2278993555 ns/op
Benchmark_parallelMergesortV1-4      17525998709 ns/op
Benchmark_parallelMergesortV2-4       1313010260 ns/op

Compare the sequential, unbounded-parallel, and thresholded-parallel benchmark results before choosing an implementation. section 8.2.2

Parallel tests have a separate control: call t.Parallel() in tests that may run together. Go runs sequential tests first, then resumes parallel tests; the default simultaneous-test limit equals GOMAXPROCS. Use go test -parallel 16 . to change that limit, for example when long-running tests spend substantial time on I/O. section 11.3.1

=== RUN   TestA
=== PAUSE TestA           #1
=== RUN   TestB
=== PAUSE TestB           #2
=== RUN   TestC           #3
--- PASS: TestC (0.00s)
=== CONT  TestA           #4
--- PASS: TestA (0.00s)
=== CONT  TestB
--- PASS: TestB (0.00s)
PASS

The test log shows two parallel tests pausing until the sequential test finishes, then resuming. section 11.3.1

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Works through merge-sort implementations and benchmark results, then gives test scheduling controls; stops short of prescribing a universal workload threshold.
Examples
Uses duplicated coffee-shop equipment, sequential and parallel merge sort, benchmark timings, and a paused-and-resumed test log.
What it assumes
Assumes familiarity with Go functions, slices, goroutines, and tests while defining parallelism against concurrency before discussing scheduling.
What you can do after
Evaluate/understand it through sequential-versus-parallel benchmarks, and operate/configure it in tests with t.Parallel() and go test -parallel.
How it connects
Connects parallelism to concurrency, goroutines, Go scheduling, synchronization, GOMAXPROCS, and benchmarking.

Also explained in

Compare how 38 books explain parallelism →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.