← Advanced course and all videos

Video 24 of 53 · 3:25 · Applications, benchmarking and evidence

Parallel work and complete request cost

In this video

  1. 0:00 · Introduction
  2. 0:16 · Follow a parallel request from split to delivery
  3. 1:19 · Core explanation
  4. 2:20 · Failure does not end buffer ownership
  5. 3:14 · Direct takeaways

Caption transcript

Show transcript
This overview explains how parallel materialization divides output work and puts the results back in their proper places. Scheduling, transfers, cleanup, and worker startup can outweigh the work saved by running pieces concurrently. Use abstract cost units for a small job. A serial worker takes four units. Splitting it evenly between two workers gives two units of computation per worker if they run concurrently. This is the useful work estimate before parallel overhead. Add one unit to split the work, one to dispatch it, two for the concurrent computation, one to merge, and one to deliver. The complete request takes six units in this illustrative schedule. Its computation stage improved, but the complete request is slower than the four-unit serial computation if comparable serial overhead is zero. For a larger job with one hundred units of serial compute, the same ideal split gives fifty units of compute plus four units of overhead. That totals fifty-four. The example explains why job size matters; it is not a measured scaling result or a guarantee of equal worker speed. Parallel materialization divides eligible output work and assembles it deterministically. Scheduling, transfers, worker lifecycle and merging remain part of a completed request. Imagine the four rows of our AB-by-CD grid arriving in the order row three, row one, row zero, row two. Their identities allow assembly into rows 0111, 0111, 0111, 1000. Arrival order must not become matrix order. This is a conceptual scheduling example, not a measured parallel run. Current code guards work, handles shared-memory cleanup, and waits for pending workers before releasing owner buffers. That repairs lifecycle behavior; it does not turn a small example into a parallel win. Fresh-pool and reused-pool requests have different preparation costs. Suppose one worker fails while another is still using shared input data. Receiving the first failure does not prove that the other worker has stopped. Its buffer remains live while that worker can still read or write it. A safe lifecycle coordinates cancellation or completion and waits until outstanding work no longer owns the data. Only then can shared storage be released. The exact API determines how this is done; the example states the ownership requirement rather than prescribing a universal cancellation call. A failed partial job must not be presented as a successful complete result. Cleanup and synchronization can also consume time. A useful parallel comparison declares whether that lifecycle work belongs to the measured boundary. Keep global indices attached to every chunk. Verify the assembled output and compare matched worker lifecycles with all overhead included.