Skip to content

perf: cache MMCQ box populations - #24

Open
2dubu wants to merge 1 commit into
mainfrom
perf/mmcq-population-cache
Open

2dubu wants to merge 1 commit into
mainfrom
perf/mmcq-population-cache

Conversation

@2dubu

@2dubu 2dubu commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Summary

Populate MMCQ's existing box population cache so queue comparisons reuse counts instead of repeatedly summing the same histogram regions.

Background

VBox.count(histogram:) checks cachedCount, but the current engine never fills it. Queue sorting and population/volume comparisons therefore rescan each box. A split already computes the partial sums needed to obtain both child populations.

Solution

Cache the initial box's count from the actual histogram, then cache both child counts from the existing split-axis partial sums after invalidating the inherited caches. Computing the initial count from the histogram preserves the supplied-histogram path, whose populations need not equal pixels.count.

The split axis, cut location, averages, queue ordering, and histogram precision are unchanged.

Related Issue

N/A.

Verification

  • Added deterministic ordered-result tests for repeated splits on each RGB axis, plus supplied-histogram populations that differ from input length and a terminal box with a supplied population. The exact goldens were captured from the unmodified base and the new tests also pass there.
  • Existing empty, unique-color, terminal, fallback-axis, queue-progress, cancellation, and Metal parity coverage remains in place.
  • Added opt-in K=10/K=16 core benchmarks with deterministic 100,000-pixel input and output checksums.
  • Commands run:
    • swift package resolve
    • swift build -c debug
    • swift test --filter MmcqQuantizerTests — 14 CPU/Metal tests passed.
    • swift test --filter PaletteKitTests --filter PaletteKitInsightsTests — 61 tests passed.
    • swift test -c release --filter MmcqQuantizerTests — 14 CPU/Metal tests passed.
    • swift test -c release --skip-build --filter MmcqQuantizerBenchmarks — 2 benchmarks passed in each comparison run.
    • git diff --check
  • Environment: Apple M5 Max, macOS 26.6.2, Swift 6.3.2. Native Mac measurements; iOS Simulator coverage runs in PR CI. No iPhone performance result is claimed.

Compatibility and Impact

  • Public API: None.
  • Behavioral impact: Intended quantized colors, populations, ordering, errors, and cancellation behavior are unchanged.
  • Performance impact: Avoid repeated histogram-region summation without adding a histogram prefix table or changing the queue data structure. Exact-color shortcuts continue to bypass this work.
  • Affected platforms: Shared CPU MMCQ engine on iOS and macOS, including the engine's externally supplied histogram path.

Additional Context

Release medians per quantization for a deterministic 100,000-pixel sampled gradient. Each clock sample contains 20 quantizations plus identical output-checksum work; values below divide by 20. There are 15 clock samples per case across three process runs with order alternated.

Core quantization Base 2286664 Cached Lower latency
10 colors 0.625 ms 0.242 ms 61.3%
16 colors 0.900 ms 0.258 ms 71.4%

Reproduce with swift test -c release --filter MmcqQuantizerBenchmarks. For the baseline, use 2286664 with only the new benchmark file copied unchanged. Input generation and warmup are outside the measured region. These results measure MMCQ plus the checksum, not image decode, color conversion, the full extractor, or iPhone performance. Low-color shortcut/terminal workloads should not be expected to show these speedups.

This branch is based directly on main and is independent of the transfer-function LUT change.

Checklist

  • This pull request is focused and contains no unrelated changes.
  • Tests were added or updated where behavior changed, or I explained why they are not needed.
  • Regression tests cover the intended behavior or root cause rather than only a reported sample.
  • Public API changes are documented and reflected in the changelog, or this pull request has none.
  • I considered source compatibility, behavioral changes, and performance impact.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant