Skip to content

Extension: Three Memory Strategies for the Parallel Engine ​

In this extension you will implement the parallel Game of Life three times, then benchmark and compare the designs and explain your findings. All three use the decomposition from Step 2: gol.Params.Threads worker goroutines, each responsible for a horizontal strip of the board. They differ only in how memory for the next generation is managed.

ApproachSummary
1Heap allocationEach worker allocates fresh memory for its strip in every iteration.
2Double bufferSource and destination grids are allocated once; the pointers are switched after each iteration.
3Map-reduceWorkers push the coordinates of cells to be flipped into a buffered channel, which is processed to update the board.

Then complete Benchmarking and Testing, which sets out how to verify and measure the implementations, and contains the analysis questions and report guidance for each approach.

Overview ​

1 · Heap allocationworld tworld t+1 (new)workers: make() every turnworld t → garbage → GCMemory: grows then collectedSync: your design2 · Double buffersrc (A)dst (B)swap pointers after barrierMemory: constant (2 grids)Sync: your design3 · Map-reduceworkerschan Cellreducerone world, flipped in placeMemory: 1 grid + flip listSync: your designAll three: identical strips, identical kernel, identical Engine interface.

Ground rules ​

  • All three implementations must be correct. Each must pass every test your parallel implementation is marked against (TestGol, TestAlive, TestPgm, TestKeyboard, TestSdl) and be free of data races (go test ./tests -race).
  • Keep the comparison fair. The only thing that should differ between approaches is the memory strategy. Use the same cell-update logic, the same way of splitting the board into strips, and the same inputs in all three; otherwise you cannot attribute a performance difference to the design.
  • Respect the full set of features. Each approach must still support the ticker, PGM output, keyboard controls and SDL events from Steps 3 to 6. Think about what each design means for producing CellFlipped / CellsFlipped events and for saving a snapshot while the game is running.

Suggested order of work ​

  1. Get your single design from Steps 1 to 6 working and passing the tests; this is your baseline.
  2. Implement each approach in turn, running the full test-suite before moving on.
  3. Build the correctness and benchmarking harness described in Benchmarking and Testing.
  4. Measure, profile, and answer the analysis questions in Benchmarking and Testing.