@nklisch/pi-agile-workflow 0.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +10 -0
- package/.codex-plugin/plugin.json +28 -0
- package/CHANGELOG.md +591 -0
- package/README.md +107 -0
- package/docs/ARCHITECTURE.md +716 -0
- package/docs/MIGRATION.md +419 -0
- package/docs/PRINCIPLES.md +464 -0
- package/docs/ROADMAP.md +95 -0
- package/docs/SPEC.md +855 -0
- package/docs/VISION.md +106 -0
- package/extensions/agile-workflow.test.ts +419 -0
- package/extensions/agile-workflow.ts +467 -0
- package/hooks/hooks.json +52 -0
- package/hooks/scripts/prompt-context.py +628 -0
- package/hooks/scripts/substrate-maintainer.py +359 -0
- package/hooks/scripts/test_prompt_context.py +757 -0
- package/package.json +30 -0
- package/scripts/install-work-view.sh +165 -0
- package/scripts/tests/agent-metadata.test.sh +75 -0
- package/scripts/tests/bump-version.test.sh +552 -0
- package/scripts/tests/channel-parity.test.sh +117 -0
- package/scripts/tests/convert-content-integrity.test.sh +246 -0
- package/scripts/tests/convert-install-routing.test.sh +159 -0
- package/scripts/tests/install-work-view.test.sh +411 -0
- package/scripts/tests/pi-package-metadata.test.sh +119 -0
- package/scripts/tests/work-board-shim.test.sh +239 -0
- package/scripts/tests/work-view-dist-version.test.sh +105 -0
- package/scripts/work-board.sh +64 -0
- package/scripts/work-view.sh +423 -0
- package/skills/autopilot/SKILL.md +330 -0
- package/skills/autopilot/agents/openai.yaml +6 -0
- package/skills/board/SKILL.md +62 -0
- package/skills/board/agents/openai.yaml +6 -0
- package/skills/bold-refactor/SKILL.md +244 -0
- package/skills/bold-refactor/agents/openai.yaml +6 -0
- package/skills/bug-scan/SKILL.md +378 -0
- package/skills/bug-scan/agents/openai.yaml +6 -0
- package/skills/bug-scan/references/async-promises.md +119 -0
- package/skills/bug-scan/references/concurrency-races.md +148 -0
- package/skills/bug-scan/references/data-layer.md +167 -0
- package/skills/bug-scan/references/error-handling.md +197 -0
- package/skills/bug-scan/references/gate-item-template.md +94 -0
- package/skills/bug-scan/references/language-footguns.md +219 -0
- package/skills/bug-scan/references/parked-item-template.md +103 -0
- package/skills/bug-scan/references/report-template.md +115 -0
- package/skills/bug-scan/references/resource-leaks.md +199 -0
- package/skills/bug-scan/references/state-closures.md +148 -0
- package/skills/bug-scan/references/time-numbers.md +158 -0
- package/skills/convert/SKILL.md +1463 -0
- package/skills/convert/agents/openai.yaml +6 -0
- package/skills/convert/references/legacy-overlap-migration.md +179 -0
- package/skills/deep-code-scan/SKILL.md +378 -0
- package/skills/deep-code-scan/agents/openai.yaml +6 -0
- package/skills/deep-code-scan/references/artifact-ledger.md +148 -0
- package/skills/deep-code-scan/references/consolidation.md +91 -0
- package/skills/deep-code-scan/references/decomposition.md +127 -0
- package/skills/deep-code-scan/references/item-templates.md +263 -0
- package/skills/deep-code-scan/references/lane-catalog.md +129 -0
- package/skills/deep-code-scan/references/review-gauntlet.md +108 -0
- package/skills/deep-code-scan/references/scanner-brief.md +152 -0
- package/skills/e2e-test-design/SKILL.md +517 -0
- package/skills/e2e-test-design/references/anti-tautology.md +261 -0
- package/skills/e2e-test-design/references/service-mocks.md +234 -0
- package/skills/e2e-test-design/references/test-taxonomy.md +211 -0
- package/skills/epic-design/SKILL.md +476 -0
- package/skills/epicize/SKILL.md +210 -0
- package/skills/epicize/agents/openai.yaml +6 -0
- package/skills/feature-design/SKILL.md +472 -0
- package/skills/fix/SKILL.md +173 -0
- package/skills/gate-cruft/SKILL.md +258 -0
- package/skills/gate-docs/SKILL.md +278 -0
- package/skills/gate-patterns/SKILL.md +389 -0
- package/skills/gate-refactor/SKILL.md +408 -0
- package/skills/gate-security/SKILL.md +275 -0
- package/skills/gate-tests/SKILL.md +367 -0
- package/skills/groom/SKILL.md +162 -0
- package/skills/groom/agents/openai.yaml +6 -0
- package/skills/ideate/SKILL.md +185 -0
- package/skills/ideate/agents/openai.yaml +6 -0
- package/skills/implement/SKILL.md +288 -0
- package/skills/implement-orchestrator/SKILL.md +604 -0
- package/skills/park/SKILL.md +111 -0
- package/skills/perf-design/SKILL.md +427 -0
- package/skills/perf-scout/SKILL.md +404 -0
- package/skills/perf-scout/agents/openai.yaml +6 -0
- package/skills/perf-scout/references/algorithmic-and-data-structures.md +126 -0
- package/skills/perf-scout/references/approximation-and-precomputation.md +136 -0
- package/skills/perf-scout/references/caching-and-memoization.md +123 -0
- package/skills/perf-scout/references/compiler-runtime-and-language.md +136 -0
- package/skills/perf-scout/references/database-and-storage-internals.md +144 -0
- package/skills/perf-scout/references/distributed-systems.md +150 -0
- package/skills/perf-scout/references/game-engine-and-realtime.md +136 -0
- package/skills/perf-scout/references/gpu-and-accelerators.md +130 -0
- package/skills/perf-scout/references/idea-ranking.md +75 -0
- package/skills/perf-scout/references/io-and-batching.md +135 -0
- package/skills/perf-scout/references/memory-and-data-locality.md +137 -0
- package/skills/perf-scout/references/parallelism-and-vectorization.md +126 -0
- package/skills/perf-scout/references/parked-item-template.md +117 -0
- package/skills/perf-scout/references/peer-review-pass.md +150 -0
- package/skills/perf-scout/references/report-template.md +148 -0
- package/skills/principles/SKILL.md +678 -0
- package/skills/principles/references/models.md +191 -0
- package/skills/principles/references/subagents.md +158 -0
- package/skills/prose-author/SKILL.md +185 -0
- package/skills/refactor-conventions-creator/SKILL.md +359 -0
- package/skills/refactor-conventions-creator/agents/openai.yaml +6 -0
- package/skills/refactor-conventions-creator/references/common-structures.md +91 -0
- package/skills/refactor-conventions-creator/references/common-styles.md +90 -0
- package/skills/refactor-design/SKILL.md +384 -0
- package/skills/release-deploy/SKILL.md +667 -0
- package/skills/release-deploy/agents/openai.yaml +6 -0
- package/skills/research/SKILL.md +166 -0
- package/skills/research/agents/openai.yaml +6 -0
- package/skills/review/SKILL.md +267 -0
- package/skills/review/references/deep-review.md +98 -0
- package/skills/review/references/review-lenses.md +68 -0
- package/skills/review/references/substrate-side-effects.md +161 -0
- package/skills/review/references/target-resolution.md +52 -0
- package/skills/scope/SKILL.md +486 -0
- package/work-view/Cargo.lock +486 -0
- package/work-view/Cargo.toml +9 -0
- package/work-view/crates/cli/.work-view-version +1 -0
- package/work-view/crates/cli/Cargo.toml +18 -0
- package/work-view/crates/cli/src/actionable.rs +500 -0
- package/work-view/crates/cli/src/args.rs +792 -0
- package/work-view/crates/cli/src/board/assets/board.css +855 -0
- package/work-view/crates/cli/src/board/assets/board.js +259 -0
- package/work-view/crates/cli/src/board/assets/card.js +139 -0
- package/work-view/crates/cli/src/board/assets/components.css +290 -0
- package/work-view/crates/cli/src/board/assets/dependency.js +1193 -0
- package/work-view/crates/cli/src/board/assets/detail.js +256 -0
- package/work-view/crates/cli/src/board/assets/filters.js +389 -0
- package/work-view/crates/cli/src/board/assets/index.html +77 -0
- package/work-view/crates/cli/src/board/assets/kanban.js +231 -0
- package/work-view/crates/cli/src/board/assets/markdown.js +260 -0
- package/work-view/crates/cli/src/board/assets/motion.css +131 -0
- package/work-view/crates/cli/src/board/assets/state.js +245 -0
- package/work-view/crates/cli/src/board/assets/table.js +304 -0
- package/work-view/crates/cli/src/board/assets/tokens.css +602 -0
- package/work-view/crates/cli/src/board/assets/views.js +41 -0
- package/work-view/crates/cli/src/board/assets.rs +162 -0
- package/work-view/crates/cli/src/board/feed.rs +204 -0
- package/work-view/crates/cli/src/board/mod.rs +246 -0
- package/work-view/crates/cli/src/board/open.rs +144 -0
- package/work-view/crates/cli/src/board/server.rs +407 -0
- package/work-view/crates/cli/src/main.rs +195 -0
- package/work-view/crates/cli/src/render.rs +354 -0
- package/work-view/crates/cli/src/scope.rs +157 -0
- package/work-view/crates/cli/src/stale.rs +581 -0
- package/work-view/crates/cli/tests/board-js/dependency-table.test.mjs +64 -0
- package/work-view/crates/cli/tests/board-js/expanded-browsing.test.mjs +79 -0
- package/work-view/crates/cli/tests/board-js/harness-smoke.test.mjs +11 -0
- package/work-view/crates/cli/tests/board-js/harness.mjs +437 -0
- package/work-view/crates/cli/tests/board-js/kanban-detail.test.mjs +75 -0
- package/work-view/crates/cli/tests/board-js/markdown-filter.test.mjs +60 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/CONVENTIONS.md +3 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/epics/epic-alpha.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-a.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-b.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-alpha-1.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-research-1.md +19 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-done.md +16 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-shipped.md +18 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/backlog/idea-backlog.md +7 -0
- package/work-view/crates/cli/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/CONVENTIONS.md +6 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-dep-done.md +17 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-design-ready.md +17 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-impl-ready.md +17 -0
- package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/stories/story-review-ready.md +17 -0
- package/work-view/crates/cli/tests/fixtures/with-malformed/.work/CONVENTIONS.md +4 -0
- package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/epics/malformed-no-closing-fence.md +8 -0
- package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/features/good-item.md +16 -0
- package/work-view/crates/cli/tests/integration.rs +2833 -0
- package/work-view/crates/core/Cargo.toml +13 -0
- package/work-view/crates/core/src/error.rs +61 -0
- package/work-view/crates/core/src/filter.rs +804 -0
- package/work-view/crates/core/src/graph.rs +324 -0
- package/work-view/crates/core/src/index.rs +590 -0
- package/work-view/crates/core/src/lib.rs +54 -0
- package/work-view/crates/core/src/model.rs +202 -0
- package/work-view/crates/core/src/parse.rs +494 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/CONVENTIONS.md +15 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/epics/epic-core.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-parser.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-query.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/malformed-no-id.md +15 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-parse-unit.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-security-gate.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-old.md +16 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-parser.md +17 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/backlog/idea-future-board.md +7 -0
- package/work-view/crates/core/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
- package/work-view/crates/core/tests/fixtures/precedence/.work/CONVENTIONS.md +10 -0
- package/work-view/crates/core/tests/fixtures/precedence/.work/archive/dup-item.md +18 -0
- package/work-view/crates/core/tests/fixtures/precedence/.work/releases/v2.0/dup-item.md +18 -0
- package/work-view/crates/core/tests/integration.rs +541 -0
- package/work-view/dist/.gitattributes +1 -0
- package/work-view/dist/README.md +42 -0
- package/work-view/dist/aarch64-apple-darwin/work-view +0 -0
- package/work-view/dist/aarch64-unknown-linux-musl/work-view +0 -0
- package/work-view/dist/x86_64-apple-darwin/work-view +0 -0
- package/work-view/dist/x86_64-unknown-linux-musl/work-view +0 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Distributed Systems — Perf-Scout Strategy Lens
|
|
2
|
+
|
|
3
|
+
> **When to load this lens**: multi-node/service code, queues, RPC, replication,
|
|
4
|
+
> cross-region calls, coordination, fan-out/fan-in, shared databases under load.
|
|
5
|
+
>
|
|
6
|
+
> **Where these ideas come from**: large-scale distributed systems (search,
|
|
7
|
+
> storage, streaming), CDNs, and the queueing-theory school of tail-latency
|
|
8
|
+
> control. The wins here are about *moving work, spreading load, and cutting
|
|
9
|
+
> coordination* — and they often trade consistency for speed, so each candidate
|
|
10
|
+
> must name what consistency it gives up. Every entry is a *candidate* hypothesis,
|
|
11
|
+
> not a proven win. Cite `file:line`, attribute the source, give a validation path.
|
|
12
|
+
|
|
13
|
+
## Detection signals (where this lens might apply — not proof)
|
|
14
|
+
- A single shared DB/service under load from many clients (hot partition risk).
|
|
15
|
+
- Synchronous cross-service/cross-region calls on a user-facing path.
|
|
16
|
+
- Fan-out to many backends where one slow node stalls the whole response (tail latency).
|
|
17
|
+
- Strong-consistency coordination (locks, two-phase, leader round-trips) on a hot path.
|
|
18
|
+
- Unbounded queues / no backpressure; load spikes cause collapse.
|
|
19
|
+
- Read-heavy data served from a single primary.
|
|
20
|
+
- Per-request work that could be precomputed/streamed/pushed.
|
|
21
|
+
|
|
22
|
+
## Strategies
|
|
23
|
+
|
|
24
|
+
### 1. Partition / shard by key
|
|
25
|
+
- **Borrowed from**: distributed databases, search indexes.
|
|
26
|
+
- **The idea**: split data and load across shards by a key so no single node is the bottleneck; route each request to its shard.
|
|
27
|
+
- **Code signals**: one DB/instance serving all keys; a hot table/partition.
|
|
28
|
+
- **Speculative win**: throughput could scale toward shard count if keys are well-distributed; smaller per-node working set.
|
|
29
|
+
- **Cost / risk**: cross-shard queries and rebalancing; hot-key skew.
|
|
30
|
+
- **Validate by**: per-shard load distribution; throughput under partitioned load.
|
|
31
|
+
|
|
32
|
+
### 2. Read replicas / read-write split
|
|
33
|
+
- **Borrowed from**: database replication, CQRS.
|
|
34
|
+
- **The idea**: serve reads from replicas and reserve the primary for writes; scale reads horizontally.
|
|
35
|
+
- **Code signals**: read-heavy workload all hitting the primary.
|
|
36
|
+
- **Speculative win**: read throughput might scale toward replica count if reads dominate and lag is tolerable.
|
|
37
|
+
- **Cost / risk**: replication lag → stale reads; routing logic.
|
|
38
|
+
- **Validate by**: read QPS capacity; staleness tolerance check.
|
|
39
|
+
|
|
40
|
+
### 3. Consistent hashing for placement
|
|
41
|
+
- **Borrowed from**: Karger et al. 1997 (consistent hashing / random trees); adopted by Dynamo and distributed caches.
|
|
42
|
+
- **The idea**: place keys on nodes via consistent hashing so adding/removing a node remaps only ~1/N of keys instead of reshuffling everything.
|
|
43
|
+
- **Code signals**: modulo-based sharding that reshuffles everything on resize; cache cold-start after scaling.
|
|
44
|
+
- **Speculative win**: minimal data movement on topology change; stable cache hit rates.
|
|
45
|
+
- **Cost / risk**: plain consistent hashing balances no better than random, so hot keys still overload a node; needs virtual nodes, and the *consistent-hashing-with-bounded-loads* variant (Mirrokni & Thorup, Google 2016/2018) to cap per-node load.
|
|
46
|
+
- **Validate by**: remap fraction on node change; per-node load balance under skewed keys.
|
|
47
|
+
|
|
48
|
+
### 4. Tail-latency hedging / speculative retries
|
|
49
|
+
- **Borrowed from**: Dean & Barroso, "The Tail at Scale" (2013) — hedged and tied requests; search backends.
|
|
50
|
+
- **The idea**: when a fan-out request is slow past a percentile, send a duplicate to another replica and take the first to respond (hedged); or enqueue on two replicas that cancel each other once one starts (tied requests), cutting wasted work.
|
|
51
|
+
- **Code signals**: p99 dominated by a few slow backends in a fan-out; one slow node stalling responses.
|
|
52
|
+
- **Speculative win**: large p99/p999 reduction with small extra load (the paper reports a hedge after a 10ms delay cut p99.9 dramatically for ~2% more requests).
|
|
53
|
+
- **Cost / risk**: extra request volume that can backpressure a loaded downstream; diminishing returns at the tail; safe only for idempotent reads.
|
|
54
|
+
- **Validate by**: p99/p999 with hedging on/off; measure added load; tune the hedge-delay percentile.
|
|
55
|
+
|
|
56
|
+
### 5. Backpressure & load shedding
|
|
57
|
+
- **Borrowed from**: reactive streams, network flow control.
|
|
58
|
+
- **The idea**: bound queues and propagate backpressure; shed or degrade low-priority load before the system collapses, instead of unbounded buffering.
|
|
59
|
+
- **Code signals**: unbounded in-memory queues; latency climbing without limit under spikes.
|
|
60
|
+
- **Speculative win**: graceful degradation; bounded latency; avoids cascading failure (a stability + latency win).
|
|
61
|
+
- **Cost / risk**: dropping/deferring work; priority policy.
|
|
62
|
+
- **Validate by**: latency and success rate under overload tests.
|
|
63
|
+
|
|
64
|
+
### 6. Locality-aware routing / edge
|
|
65
|
+
- **Borrowed from**: CDNs, geo-distributed systems.
|
|
66
|
+
- **The idea**: serve from the node/region nearest the data or the user; cache/compute at the edge to cut round-trip distance.
|
|
67
|
+
- **Code signals**: cross-region calls on a user path; static/derivable content fetched from a distant origin.
|
|
68
|
+
- **Speculative win**: could lower network latency and origin load if requests are geographically dispersed.
|
|
69
|
+
- **Cost / risk**: data placement and invalidation across regions.
|
|
70
|
+
- **Validate by**: per-region latency; edge hit rate.
|
|
71
|
+
|
|
72
|
+
### 7. Relax consistency where the domain allows (eventual / CRDT)
|
|
73
|
+
- **Borrowed from**: Dynamo (eventual consistency); CRDTs (Shapiro, Preguiça, Baquero & Zawirski 2011 — strong eventual consistency).
|
|
74
|
+
- **The idea**: replace strong coordination with eventual consistency or conflict-free replicated data types where the use case tolerates it, removing coordination from the hot path. CRDTs converge without consensus by construction.
|
|
75
|
+
- **Code signals**: distributed locks/2PC/leader round-trips guarding data that could converge instead.
|
|
76
|
+
- **Speculative win**: might remove coordination latency and raise availability/throughput if the domain tolerates the relaxed model.
|
|
77
|
+
- **Cost / risk**: weaker guarantees; CRDT convergence/merge semantics (state- vs op-based) must fit the domain, and metadata can grow. High design cost.
|
|
78
|
+
- **Validate by**: latency without coordination; correctness against the relaxed model.
|
|
79
|
+
|
|
80
|
+
### 8. Asynchronous / queue-decoupled work
|
|
81
|
+
- **Borrowed from**: message queues, event-driven architectures.
|
|
82
|
+
- **The idea**: move non-critical work (emails, indexing, analytics, derived updates) off the request path onto a queue/worker; return to the user sooner.
|
|
83
|
+
- **Code signals**: user request blocks on slow side effects not needed for the response.
|
|
84
|
+
- **Speculative win**: request latency may drop toward the critical path if the deferred work is truly off the response; smooths spikes.
|
|
85
|
+
- **Cost / risk**: eventual completion; failure/retry semantics; ordering.
|
|
86
|
+
- **Validate by**: request latency before/after; queue lag monitoring.
|
|
87
|
+
|
|
88
|
+
### 9. Batch / stream across the wire
|
|
89
|
+
- **Borrowed from**: gRPC streaming, Kafka batching.
|
|
90
|
+
- **The idea**: batch many small RPCs into one, or stream results, instead of one request-response per item; coalesce cross-service chatter.
|
|
91
|
+
- **Code signals**: per-item RPC in a loop across a service boundary; chatty microservice calls.
|
|
92
|
+
- **Speculative win**: could cut round-trips and per-call overhead if calls are batchable and not already pipelined.
|
|
93
|
+
- **Cost / risk**: batch error handling; streaming backpressure.
|
|
94
|
+
- **Validate by**: round-trip count; throughput.
|
|
95
|
+
|
|
96
|
+
### 10. CQRS / precomputed read models
|
|
97
|
+
- **Borrowed from**: event sourcing, CQRS.
|
|
98
|
+
- **The idea**: maintain denormalized read models updated from a write/event log so reads are simple lookups instead of expensive cross-aggregate queries.
|
|
99
|
+
- **Code signals**: complex multi-join/aggregate queries rebuilt per read; read and write shapes fighting each other.
|
|
100
|
+
- **Speculative win**: reads could become cheap lookups if the read model fits the query shape; read and write paths may scale independently.
|
|
101
|
+
- **Cost / risk**: eventual consistency of the read model; projection maintenance.
|
|
102
|
+
- **Validate by**: read latency; projection lag.
|
|
103
|
+
|
|
104
|
+
### 11. Colocate compute with data
|
|
105
|
+
- **Borrowed from**: map-reduce data locality, stored procedures, pushdown.
|
|
106
|
+
- **The idea**: move the computation to where the data lives (push filters/aggregations into the store, run logic in the DB or near the dataset) instead of shipping large data to the compute.
|
|
107
|
+
- **Code signals**: pulling large result sets to the app to filter/aggregate; ship-data-to-code patterns.
|
|
108
|
+
- **Speculative win**: could cut data movement, network, and serialization if the filter/aggregation is highly reductive.
|
|
109
|
+
- **Cost / risk**: logic in the data tier is harder to test/version; portability.
|
|
110
|
+
- **Validate by**: bytes moved; end-to-end latency.
|
|
111
|
+
|
|
112
|
+
### 12. Adaptive / least-loaded routing
|
|
113
|
+
- **Borrowed from**: power-of-two-choices (Mitzenmacher et al.), join-shortest-queue load balancing.
|
|
114
|
+
- **The idea**: instead of round-robin or random, sample two backends and route to the less-loaded one (fewest in-flight requests). Cheap partial state buys exponentially better balance than blind routing.
|
|
115
|
+
- **Code signals**: round-robin/random LB while one slow or warm node piles up a queue; latency variance traced to uneven backend load.
|
|
116
|
+
- **Speculative win**: might flatten queueing latency and the tail under load with O(1) per-request cost; no global coordination.
|
|
117
|
+
- **Cost / risk**: needs a load/inflight signal per backend; stale load info can herd traffic; ties with hedging budget.
|
|
118
|
+
- **Validate by**: per-backend queue depth and p99 under load test, round-robin vs power-of-two.
|
|
119
|
+
|
|
120
|
+
### 13. Request coalescing / single-flight dedup
|
|
121
|
+
- **Borrowed from**: single-flight, cache-stampede prevention, request collapsing at gateways.
|
|
122
|
+
- **The idea**: when many concurrent callers ask for the same key, run one backend call and fan the single result out to all waiters, instead of N identical queries. Opposite of hedging — collapses duplicates rather than spawning them.
|
|
123
|
+
- **Code signals**: hot key hit by many clients at once; thundering herd on cache miss/expiry; identical queries firing in parallel.
|
|
124
|
+
- **Speculative win**: could collapse duplicate backend work to ~1 per key, cutting DB/upstream load and tail latency on cache misses.
|
|
125
|
+
- **Cost / risk**: a stalled or failing leader call blocks/fails all waiters; only safe for read-shareable results; per-process unless backed by a distributed lock.
|
|
126
|
+
- **Validate by**: duplicate-query count and DB load under a concurrent same-key burst; latency on cache-miss storms.
|
|
127
|
+
|
|
128
|
+
### 14. Cell-based architecture (bulkhead isolation)
|
|
129
|
+
- **Borrowed from**: AWS cell-based architecture, the bulkhead pattern.
|
|
130
|
+
- **The idea**: partition the whole stack into independent, fixed-size cells (each a full replica) and route a tenant/key to one cell. Capacity scales by adding cells, and a hot or failing cell can't drag the rest down.
|
|
131
|
+
- **Code signals**: one shared pool where a single noisy tenant or partition degrades everyone; no failure-isolation boundary.
|
|
132
|
+
- **Speculative win**: might let throughput scale linearly with cell count while bounding the blast radius of overload to ~1/N of traffic (a scaling + stability candidate, not a per-request speedup).
|
|
133
|
+
- **Cost / risk**: cross-cell operations and routing/placement complexity; per-cell overhead; rebalancing tenants between cells.
|
|
134
|
+
- **Validate by**: per-cell load distribution; tail latency and error rate when one cell is saturated.
|
|
135
|
+
|
|
136
|
+
### 15. Request deadlines + cancellation propagation
|
|
137
|
+
- **Borrowed from**: gRPC deadlines (propagated across hops, unlike a per-hop timeout); Go `context` deadline/cancellation.
|
|
138
|
+
- **The idea**: give each request a single time budget and propagate it (plus cancellation) down the call chain, so when the caller's deadline passes or it abandons the request, every downstream hop stops working on it instead of finishing doomed work.
|
|
139
|
+
- **Code signals**: per-hop timeouts that don't compose into an end-to-end budget; downstream work that keeps running after the client gave up; no `context`/deadline threaded through calls.
|
|
140
|
+
- **Speculative win**: could reclaim capacity spent on already-doomed requests and tighten the tail under load if much work is currently abandoned mid-flight.
|
|
141
|
+
- **Cost / risk**: cancellation must be honored at each layer (and partial side effects undone); too-tight deadlines can amplify failures; clock-skew across services.
|
|
142
|
+
- **Validate by**: fraction of work cancelled vs completed-after-deadline; tail latency and goodput under overload with deadlines on/off.
|
|
143
|
+
|
|
144
|
+
### 16. Adaptive concurrency limits + retry budgets
|
|
145
|
+
- **Borrowed from**: Netflix concurrency-limits (AIMD / gradient limiters, after TCP congestion control — gradient = RTT_noload / RTT_actual); retry budgets; Little's Law for queue sizing.
|
|
146
|
+
- **The idea**: dynamically cap in-flight requests by watching latency (additively grow the limit while healthy, multiplicatively shrink when queueing appears) instead of a fixed pool, and cap retries as a small fraction of live traffic (a retry *budget*) so failures don't trigger a retry storm. Size any bounding queue with Little's Law (L = λ·W).
|
|
147
|
+
- **Code signals**: hand-tuned fixed thread/connection pools; per-call retries with no global cap; latency collapsing under load while a static limit stays wide open; retry amplification during partial outages.
|
|
148
|
+
- **Speculative win**: might hold throughput near the knee and prevent congestion collapse and retry storms if load is bursty and limits are currently static.
|
|
149
|
+
- **Cost / risk**: limiter can misread noisy latency and over-throttle; needs a clean RTT/inflight signal; interacts with hedging and load-balancer choices.
|
|
150
|
+
- **Validate by**: goodput and p99 under a load/overload test, static vs adaptive limit; retries as a percentage of requests during an injected downstream fault.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Game-Engine & Realtime — Perf-Scout Strategy Lens
|
|
2
|
+
|
|
3
|
+
> **When to load this lens**: per-frame/per-tick loops, simulations, spatial
|
|
4
|
+
> queries, large entity/object collections, rendering, soft real-time budgets,
|
|
5
|
+
> allocation churn inside a loop.
|
|
6
|
+
>
|
|
7
|
+
> **Where these ideas come from**: AAA game engines, physics/simulation, and
|
|
8
|
+
> real-time graphics — domains that must do enormous work inside a fixed
|
|
9
|
+
> ~16ms/frame budget, which forces the most disciplined performance engineering in
|
|
10
|
+
> software. Many of these ideas transfer surprisingly well to ordinary
|
|
11
|
+
> batch/server code. Every entry is a *candidate* hypothesis, not a proven win.
|
|
12
|
+
> Cite `file:line`, attribute the source, give a validation path.
|
|
13
|
+
|
|
14
|
+
## Detection signals (where this lens might apply — not proof)
|
|
15
|
+
- A main loop / tick / frame / step that runs over a collection every cycle.
|
|
16
|
+
- Collections of "entities"/"objects" with heterogeneous behavior iterated per cycle.
|
|
17
|
+
- Spatial queries: nearest-neighbor, range, collision, "what's near X" done by scanning all.
|
|
18
|
+
- Allocations or temporary objects created inside the per-cycle loop.
|
|
19
|
+
- Recomputing the same derived state every frame even when inputs didn't change.
|
|
20
|
+
- Processing far-away / off-screen / low-impact items at full fidelity.
|
|
21
|
+
- Variable timestep tied to frame rate; simulation jitter.
|
|
22
|
+
- Hot loop touches one field of a wide struct across a large array (cache waste).
|
|
23
|
+
|
|
24
|
+
## Strategies
|
|
25
|
+
|
|
26
|
+
### 1. Entity-Component-System (ECS) / data-oriented layout
|
|
27
|
+
- **Borrowed from**: modern game engines (Unity DOTS, Bevy, EnTT, flecs).
|
|
28
|
+
- **The idea**: store entities' components in contiguous per-component arrays and process them in tight systems, instead of arrays of polymorphic objects with virtual `update()` calls.
|
|
29
|
+
- **Code signals**: `for obj in objects: obj.update()` over heterogeneous objects; OOP entity hierarchies on a hot loop.
|
|
30
|
+
- **Speculative win**: cache-friendly streaming, vectorizable systems, no virtual-dispatch per entity.
|
|
31
|
+
- **Cost / risk**: a big architectural shift; overkill for small collections.
|
|
32
|
+
- **Validate by**: per-system benchmark; cache-miss counters — profile via perf-design.
|
|
33
|
+
|
|
34
|
+
### 2. ECS storage choice: archetype vs sparse-set
|
|
35
|
+
- **Borrowed from**: ECS internals — archetype/table storage (Unity DOTS, flecs, Bevy default) vs sparse-set storage (EnTT, Bevy's opt-in `SparseSet`).
|
|
36
|
+
- **The idea**: archetype storage packs entities sharing a component set into dense tables — fast multi-component iteration, but adding/removing a component moves the entity to another table. Sparse-set storage keeps each component in its own set — cheap add/remove, slower multi-component iteration. Pick per access pattern; some engines let you choose per component.
|
|
37
|
+
- **Code signals**: ECS already in use but components churn (added/removed) every frame on a query-heavy path, or vice-versa.
|
|
38
|
+
- **Speculative win**: matching storage to the dominant operation (iterate vs mutate) could cut the cost of whichever dominates.
|
|
39
|
+
- **Cost / risk**: wrong choice penalizes the hot operation; mixed workloads may want a hybrid (flecs 4.1 / AoSoA).
|
|
40
|
+
- **Validate by**: benchmark iteration vs structural-change rates on the real workload; compare storage modes.
|
|
41
|
+
|
|
42
|
+
### 3. Spatial partitioning for proximity queries
|
|
43
|
+
- **Borrowed from**: collision detection, rendering (grids, quadtree/octree, BVH, k-d tree, spatial hash).
|
|
44
|
+
- **The idea**: index objects by position so "what's near X" / collision / range queries examine only nearby cells instead of all N objects.
|
|
45
|
+
- **Code signals**: nested loop over all pairs for collision/distance; `for a: for b: if near(a,b)`.
|
|
46
|
+
- **Speculative win**: O(n²) all-pairs → ~O(n) or O(n log n) neighbor queries.
|
|
47
|
+
- **Cost / risk**: structure maintenance as objects move; cell-size tuning.
|
|
48
|
+
- **Validate by**: query count and timing vs. object count — profile via perf-design.
|
|
49
|
+
|
|
50
|
+
### 4. Object pooling (no allocation in the loop)
|
|
51
|
+
- **Borrowed from**: game engines (bullets, particles, enemies).
|
|
52
|
+
- **The idea**: pre-allocate and recycle objects from a pool so the per-frame loop never allocates or triggers GC.
|
|
53
|
+
- **Code signals**: `new`/allocation inside the tick loop; GC pauses correlated with the loop; particle/event spawn churn.
|
|
54
|
+
- **Speculative win**: removes allocation and GC pauses from the hot loop — candidate for steadier frame time.
|
|
55
|
+
- **Cost / risk**: must fully reset reused objects; pool sizing.
|
|
56
|
+
- **Validate by**: allocations/frame; frame-time variance.
|
|
57
|
+
|
|
58
|
+
### 5. Frame / linear (arena) allocator for transient data
|
|
59
|
+
- **Borrowed from**: frame-centric engine memory (Naughty Dog frame allocators; arena/bump allocators).
|
|
60
|
+
- **The idea**: serve all per-frame scratch (temp buffers, command lists, intermediate results) from a linear allocator that bumps a pointer, then reset the whole arena to zero at end of frame — no per-object free.
|
|
61
|
+
- **Code signals**: many short-lived heap allocations whose lifetime is exactly one frame/request; `malloc`/`new` + matching frees clustered inside one cycle.
|
|
62
|
+
- **Speculative win**: allocation reduces to a pointer bump and free to one integer reset; could remove allocator contention and fragmentation from the loop.
|
|
63
|
+
- **Cost / risk**: dangling references if data outlives the frame; arena must be sized for the worst frame.
|
|
64
|
+
- **Validate by**: allocation-time and frame-time variance with arena vs general allocator; verify no escapes.
|
|
65
|
+
|
|
66
|
+
### 6. Structure-of-Arrays hot loops
|
|
67
|
+
- **Borrowed from**: data-oriented design (SoA vs AoS); SIMD-friendly layouts.
|
|
68
|
+
- **The idea**: when a hot loop reads only one or two fields of a wide record across a large array, store each field in its own array (SoA) so the loop streams only the bytes it touches and can autovectorize, instead of pulling whole structs through cache.
|
|
69
|
+
- **Code signals**: tight loop over `items[i].oneField` on a struct with many other fields; low arithmetic intensity but high memory traffic; failed autovectorization.
|
|
70
|
+
- **Speculative win**: fewer cache-line loads and unit-stride access could speed memory-bound loops and unlock SIMD.
|
|
71
|
+
- **Cost / risk**: scattered random per-record access gets worse; splitting hurts code clarity; AoSoA is a middle ground.
|
|
72
|
+
- **Validate by**: cache-miss / bandwidth counters and loop benchmark; confirm vectorization — profile via perf-design.
|
|
73
|
+
|
|
74
|
+
### 7. Dirty-flagging / change-driven recompute
|
|
75
|
+
- **Borrowed from**: scene graphs, UI layout engines, retained-mode rendering.
|
|
76
|
+
- **The idea**: recompute derived state only when its inputs change (mark dirty on mutation, recompute lazily) instead of every frame.
|
|
77
|
+
- **Code signals**: full transform/layout/derived recompute each frame regardless of change.
|
|
78
|
+
- **Speculative win**: per-cycle work drops to only what changed.
|
|
79
|
+
- **Cost / risk**: dirty-tracking correctness; missed invalidations cause stale state.
|
|
80
|
+
- **Validate by**: count recomputes/frame; benchmark with realistic change rates.
|
|
81
|
+
|
|
82
|
+
### 8. Level of Detail (LOD) / fidelity by impact
|
|
83
|
+
- **Borrowed from**: rendering, physics LOD, simulation.
|
|
84
|
+
- **The idea**: process distant/low-impact/off-screen items at reduced fidelity or lower frequency; full detail only where it matters.
|
|
85
|
+
- **Code signals**: every item processed identically regardless of relevance; far/off-screen items at full cost.
|
|
86
|
+
- **Speculative win**: large savings by spending compute where it's perceptible/important.
|
|
87
|
+
- **Cost / risk**: fidelity transitions; correctness of the impact heuristic.
|
|
88
|
+
- **Validate by**: cost per fidelity tier; quality check.
|
|
89
|
+
|
|
90
|
+
### 9. Culling (skip invisible/irrelevant work)
|
|
91
|
+
- **Borrowed from**: frustum/occlusion culling in renderers.
|
|
92
|
+
- **The idea**: cheaply reject items that can't affect the result before doing expensive work on them (bounding-box test, visibility test, relevance filter).
|
|
93
|
+
- **Code signals**: expensive per-item processing with no early reject; computing results that are then discarded/clipped.
|
|
94
|
+
- **Speculative win**: skips the majority of items when most are irrelevant.
|
|
95
|
+
- **Cost / risk**: cull test must be cheaper than the work saved; correctness of rejection.
|
|
96
|
+
- **Validate by**: cull rate; benchmark with/without.
|
|
97
|
+
|
|
98
|
+
### 10. Fixed timestep / decoupled update rate
|
|
99
|
+
- **Borrowed from**: game loops, physics integration (Gaffer on Games, "Fix Your Timestep!", Glenn Fiedler).
|
|
100
|
+
- **The idea**: run simulation at a fixed timestep accumulated independently of render/output rate for stable, cheaper, deterministic updates; interpolate between the last two states for display.
|
|
101
|
+
- **Code signals**: per-frame work scaling with frame rate; jittery or rate-dependent simulation.
|
|
102
|
+
- **Speculative win**: bounded, predictable per-cycle cost; determinism.
|
|
103
|
+
- **Cost / risk**: interpolation for display; accumulator logic; spiral-of-death if a step exceeds budget.
|
|
104
|
+
- **Validate by**: per-tick cost stability; determinism check.
|
|
105
|
+
|
|
106
|
+
### 11. Double buffering / read-write separation
|
|
107
|
+
- **Borrowed from**: rendering (front/back buffer), simulation state.
|
|
108
|
+
- **The idea**: compute next state into a separate buffer while readers use the current one, then swap — avoids locking and read-during-write hazards, enables parallel update.
|
|
109
|
+
- **Code signals**: readers and a writer contending on shared state per cycle; locks around per-frame state.
|
|
110
|
+
- **Speculative win**: lock-free reads during update; parallel-friendly.
|
|
111
|
+
- **Cost / risk**: double the memory; swap synchronization.
|
|
112
|
+
- **Validate by**: contention metrics; frame-time benchmark.
|
|
113
|
+
|
|
114
|
+
### 12. Job system / frame-budgeted parallelism
|
|
115
|
+
- **Borrowed from**: engine job systems (fork-join over a frame; Naughty Dog fiber-based job system, Gyrling, GDC 2015).
|
|
116
|
+
- **The idea**: break the frame's work into jobs scheduled across cores within the frame budget; spread the per-cycle workload over all cores.
|
|
117
|
+
- **Code signals**: single-threaded per-frame work; idle cores; a frame budget being missed.
|
|
118
|
+
- **Speculative win**: more work per frame within budget; better core use.
|
|
119
|
+
- **Cost / risk**: job dependencies; scheduler overhead for tiny jobs.
|
|
120
|
+
- **Validate by**: frame-time and core-utilization benchmark.
|
|
121
|
+
|
|
122
|
+
### 13. Batch by type / sort to reduce state changes
|
|
123
|
+
- **Borrowed from**: render-state batching, draw-call sorting.
|
|
124
|
+
- **The idea**: group like work together (same type/shader/resource) and sort to minimize expensive state switches between items.
|
|
125
|
+
- **Code signals**: interleaved heterogeneous operations each paying setup/teardown; frequent context switches per item.
|
|
126
|
+
- **Speculative win**: amortizes setup across a batch; fewer expensive transitions.
|
|
127
|
+
- **Cost / risk**: a sort/group pass; reordering must be valid.
|
|
128
|
+
- **Validate by**: state-change count; throughput.
|
|
129
|
+
|
|
130
|
+
### 14. Precompute / bake static work
|
|
131
|
+
- **Borrowed from**: lightmap baking, navmesh precomputation.
|
|
132
|
+
- **The idea**: move work that doesn't change at runtime into an offline/startup bake (precomputed tables, baked paths/visibility) so the hot loop just reads it.
|
|
133
|
+
- **Code signals**: recomputing static-input results every cycle; expensive setup repeated at runtime.
|
|
134
|
+
- **Speculative win**: removes invariant work from the runtime loop entirely.
|
|
135
|
+
- **Cost / risk**: bake step and storage; rebake on input change.
|
|
136
|
+
- **Validate by**: runtime cost with baked vs. computed data.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# GPU & Accelerators — Perf-Scout Strategy Lens
|
|
2
|
+
|
|
3
|
+
> **When to load this lens**: massively-parallel regular numeric work, large
|
|
4
|
+
> array/matrix/tensor math, image/signal processing, convolutions, existing
|
|
5
|
+
> GPU/CUDA/Metal/ROCm code, or compute-bound kernels that could move off the CPU.
|
|
6
|
+
>
|
|
7
|
+
> **Where these ideas come from**: GPU programming (CUDA, Metal, ROCm/HIP),
|
|
8
|
+
> ML kernels (cuDNN, CUTLASS), HPC, and graphics. A GPU only wins when the work
|
|
9
|
+
> has enough *arithmetic intensity* (FLOPs per byte moved) to feed thousands of
|
|
10
|
+
> threads, and host↔device transfer often dominates a naive port — so these
|
|
11
|
+
> ideas only matter once the work is regular, data-parallel, and big enough.
|
|
12
|
+
> **Pair this lens with a roofline check first** (entry 1): decide memory-bound
|
|
13
|
+
> vs compute-bound before optimizing, because the two need opposite fixes. Every
|
|
14
|
+
> entry is a *candidate* hypothesis, not a proven win. Cite `file:line`,
|
|
15
|
+
> attribute the source, give a validation path.
|
|
16
|
+
|
|
17
|
+
## Detection signals (where this lens might apply — not proof)
|
|
18
|
+
- Large element-wise / map operations over arrays (millions of elements).
|
|
19
|
+
- Dense linear algebra: matrix multiply, convolution, FFT, tensor contractions.
|
|
20
|
+
- Image, video, or signal processing done element-by-element on the CPU.
|
|
21
|
+
- Existing GPU code (`.cu`/`.metal`/HIP kernels) with hand-rolled loops.
|
|
22
|
+
- A hot numeric kernel that is regular (no data-dependent control flow) and huge.
|
|
23
|
+
- ML inference/training math, embeddings, similarity at scale.
|
|
24
|
+
- A CPU SIMD kernel already maxed out but still the bottleneck.
|
|
25
|
+
|
|
26
|
+
## Strategies
|
|
27
|
+
|
|
28
|
+
### 1. Roofline / arithmetic-intensity check (do this FIRST)
|
|
29
|
+
- **Borrowed from**: the Roofline model (Williams, Waterman & Patterson, 2008).
|
|
30
|
+
- **The idea**: before optimizing, plot the kernel's arithmetic intensity (FLOPs per byte moved) against peak compute and peak bandwidth. If it lands on the slanted bandwidth roof it is *memory-bound* (fix data movement); if on the flat roof it is *compute-bound* (fix the math/instruction mix). This decides which of the entries below even apply.
|
|
31
|
+
- **Code signals**: a kernel being tuned blind; "make it faster" with no idea whether bytes or FLOPs are the wall; a low-intensity op (axpy, copy, reduction) expected to be compute-bound.
|
|
32
|
+
- **Speculative win**: stops wasted effort — points at the *actual* ceiling so the right strategy is chosen.
|
|
33
|
+
- **Cost / risk**: requires measuring/estimating bytes and FLOPs; the model is a guide, not exact.
|
|
34
|
+
- **Validate by**: Nsight Compute roofline report (or compute the intensity by hand) to locate the kernel under the roof.
|
|
35
|
+
|
|
36
|
+
### 2. Memory coalescing
|
|
37
|
+
- **Borrowed from**: CUDA/GPU global-memory access model.
|
|
38
|
+
- **The idea**: arrange access so the 32 threads of a warp touch contiguous, aligned global-memory addresses, letting the hardware merge them into as few transactions as possible (ideally 128-byte aligned).
|
|
39
|
+
- **Code signals**: strided/scattered/transposed indexing in a kernel; each thread walking a row with a large stride; AoS layouts in device buffers.
|
|
40
|
+
- **Speculative win**: fewer DRAM transactions per warp — a candidate large jump for memory-bound kernels (uncoalesced access can split one transaction into many).
|
|
41
|
+
- **Cost / risk**: may force a layout change (SoA, transpose) elsewhere; only matters when memory-bound.
|
|
42
|
+
- **Validate by**: Nsight Compute memory-throughput / global-load-efficiency report; before/after kernel timing.
|
|
43
|
+
|
|
44
|
+
### 3. Shared-memory / on-chip tiling
|
|
45
|
+
- **Borrowed from**: tiled matmul; blocked GEMM in cuBLAS/CUTLASS.
|
|
46
|
+
- **The idea**: stage a block of data into on-chip shared memory once, then have the threads of the block reuse it many times, cutting redundant global-memory loads (classic blocked matrix multiply).
|
|
47
|
+
- **Code signals**: a kernel re-reading the same global data across threads/iterations; stencils, GEMM, convolution loading neighbors repeatedly.
|
|
48
|
+
- **Speculative win**: raises arithmetic intensity by reusing on-chip data — candidate for moving a memory-bound kernel toward compute-bound.
|
|
49
|
+
- **Cost / risk**: shared memory is scarce and caps occupancy; bank conflicts; correct tiling/sync is fiddly.
|
|
50
|
+
- **Validate by**: Nsight Compute (global traffic drop, shared-memory bank-conflict counters); compare against a library GEMM.
|
|
51
|
+
|
|
52
|
+
### 4. Occupancy vs register/shared-memory pressure
|
|
53
|
+
- **Borrowed from**: CUDA occupancy tuning.
|
|
54
|
+
- **The idea**: enough resident warps per SM are needed to hide memory latency, but each thread's registers and each block's shared memory cap how many warps fit. Trading some per-thread register use (or shared memory) for more concurrent warps — or vice versa — can be the win.
|
|
55
|
+
- **Code signals**: a kernel launching far fewer blocks than SMs; high register usage; low achieved occupancy; latency-bound kernel with idle SMs.
|
|
56
|
+
- **Speculative win**: better latency hiding and SM utilization once occupancy is the limiter.
|
|
57
|
+
- **Cost / risk**: more occupancy is not always better (register spilling hurts); needs measurement, not assumption.
|
|
58
|
+
- **Validate by**: `nvcc --ptxas-options=-v` for register/shared usage; Nsight Compute achieved-occupancy and the occupancy calculator.
|
|
59
|
+
|
|
60
|
+
### 5. Warp / wavefront divergence
|
|
61
|
+
- **Borrowed from**: SIMT execution model (CUDA warps, AMD wavefronts).
|
|
62
|
+
- **The idea**: when threads in a warp take different sides of a data-dependent branch, the warp serializes each path with the off-path threads masked. Restructure so a branch resolves uniformly across the warp (sort/partition by branch outcome, branchless predication, data reorganization).
|
|
63
|
+
- **Code signals**: `if (data[tid] > x)` style data-dependent branches inside a kernel; per-thread early-exit; ragged loop bounds across threads.
|
|
64
|
+
- **Speculative win**: removes serialized branch paths within a warp — candidate when divergence is high.
|
|
65
|
+
- **Cost / risk**: reorganizing data to align branches has its own cost; only helps if divergence is actually significant.
|
|
66
|
+
- **Validate by**: Nsight Compute branch-efficiency / warp-execution-efficiency counters; before/after timing.
|
|
67
|
+
|
|
68
|
+
### 6. Kernel fusion
|
|
69
|
+
- **Borrowed from**: ML compilers / elementwise fusion (cuDNN, XLA, Triton).
|
|
70
|
+
- **The idea**: fuse a chain of elementwise or producer→consumer kernels into one, so intermediates stay in registers/shared memory instead of round-tripping through global memory, and you pay one launch instead of many.
|
|
71
|
+
- **Code signals**: several small kernels run back-to-back over the same arrays; `a = f(x); b = g(a); c = h(b)` each as its own launch; a temp buffer written then immediately re-read.
|
|
72
|
+
- **Speculative win**: fewer launches and global-memory round-trips — candidate for memory-bound elementwise chains.
|
|
73
|
+
- **Cost / risk**: a fused kernel uses more registers/shared memory (can cut occupancy); harder to read; less reuse across call sites.
|
|
74
|
+
- **Validate by**: count launches + global traffic in Nsight Systems/Compute; before/after end-to-end timing.
|
|
75
|
+
|
|
76
|
+
### 7. Host↔device transfer amortization
|
|
77
|
+
- **Borrowed from**: CUDA streams / async copy; pinned-memory DMA.
|
|
78
|
+
- **The idea**: stop paying PCIe round-trips per call — keep data resident on the device across operations, batch transfers, use pinned (page-locked) host memory for faster DMA, and overlap copy with compute using non-default streams (copy chunk i+1 while computing chunk i).
|
|
79
|
+
- **Code signals**: copy-up → one kernel → copy-down repeated in a loop; pageable host buffers; default-stream-only code; transfer time rivaling kernel time.
|
|
80
|
+
- **Speculative win**: hides or removes transfer cost — often the single biggest factor in whether a GPU port wins at all.
|
|
81
|
+
- **Cost / risk**: pinned memory is a limited resource; stream/overlap logic adds complexity; overlap needs separate non-default streams + pinned host memory.
|
|
82
|
+
- **Validate by**: Nsight Systems timeline (copy vs compute overlap); measure host-device transfer time vs kernel time explicitly.
|
|
83
|
+
|
|
84
|
+
### 8. Mixed precision (fp16 / bf16 / tf32)
|
|
85
|
+
- **Borrowed from**: mixed-precision ML training/inference (NVIDIA AMP).
|
|
86
|
+
- **The idea**: where accuracy tolerates it, run in fp16/bf16/tf32 instead of fp32 — roughly halving bytes moved and unlocking higher math throughput, optionally keeping a higher-precision accumulator.
|
|
87
|
+
- **Code signals**: fp32-everywhere numeric kernels; ML inference; large arrays where a few bits of mantissa do not change the result materially.
|
|
88
|
+
- **Speculative win**: less memory traffic and higher throughput — candidate when the workload is tolerant.
|
|
89
|
+
- **Cost / risk**: accuracy loss, overflow/underflow (bf16 range vs fp16 precision); needs numerical validation; not safe everywhere.
|
|
90
|
+
- **Validate by**: accuracy/error check against the fp32 baseline; bandwidth + timing on the reduced-precision kernel.
|
|
91
|
+
|
|
92
|
+
### 9. Tensor-core / MMA fit
|
|
93
|
+
- **Borrowed from**: NVIDIA Tensor Cores / matrix engines; CUTLASS MMA tiling.
|
|
94
|
+
- **The idea**: matrix-multiply-accumulate hardware only fires when data type, layout, and tile shape match what the matrix engine wants (e.g. CUTLASS warp-level MMA tiles like 16×8×8). Shaping the problem as tiled GEMM in a supported precision lets the matrix units do the work.
|
|
95
|
+
- **Code signals**: matmul/conv/attention implemented as plain fp32 loops; GEMM-shaped math not hitting tensor cores; awkward tile dimensions.
|
|
96
|
+
- **Speculative win**: routes the math onto dedicated matrix units — a candidate large jump for GEMM-shaped, precision-tolerant work.
|
|
97
|
+
- **Cost / risk**: strict shape/alignment/precision constraints; hardware-specific; easy to *think* you are using tensor cores when you are not.
|
|
98
|
+
- **Validate by**: Nsight Compute tensor-core-utilization (pipe-active) counters; compare against cuBLAS/CUTLASS for the same op.
|
|
99
|
+
|
|
100
|
+
### 10. Read-only / constant / texture memory paths
|
|
101
|
+
- **Borrowed from**: CUDA memory hierarchy (constant cache, read-only `__ldg`/texture path).
|
|
102
|
+
- **The idea**: route data that is constant for the kernel's lifetime through specialized cached paths — constant memory for warp-uniform broadcasts, the read-only data cache (`const __restrict__` / `__ldg`) for reused read-only inputs — to relieve the general L1/global path.
|
|
103
|
+
- **Code signals**: lookup tables, filter weights, or coefficients read by every thread; read-only inputs not marked `const __restrict__`; broadcast-style same-address reads.
|
|
104
|
+
- **Speculative win**: extra effective cache and broadcast for read-only data — candidate when reuse is high.
|
|
105
|
+
- **Cost / risk**: constant memory is tiny; only helps specific access patterns (uniform broadcast / heavily reused read-only); easy to misapply.
|
|
106
|
+
- **Validate by**: Nsight Compute cache hit-rate counters on the relevant path; before/after timing.
|
|
107
|
+
|
|
108
|
+
### 11. Batch small kernels / more work per launch
|
|
109
|
+
- **Borrowed from**: batched BLAS; CUDA Graphs; launch-latency amortization.
|
|
110
|
+
- **The idea**: many tiny launches are dominated by per-launch overhead — batch them (batched GEMM, a grid covering all items, or a CUDA Graph capturing the sequence) so each launch does enough work to amortize the cost.
|
|
111
|
+
- **Code signals**: a host loop launching one small kernel per item; thousands of micro-launches; grids far smaller than the device.
|
|
112
|
+
- **Speculative win**: launch overhead amortized across more work — candidate when launches dominate over compute.
|
|
113
|
+
- **Cost / risk**: batching needs uniform-ish work; CUDA Graphs add capture/update complexity; oversized grids can hurt locality.
|
|
114
|
+
- **Validate by**: Nsight Systems launch density / gaps on the timeline; before/after throughput.
|
|
115
|
+
|
|
116
|
+
### 12. Use a tuned library/primitive over a hand-rolled kernel
|
|
117
|
+
- **Borrowed from**: cuBLAS, cuDNN, CUTLASS, Thrust; Metal Performance Shaders.
|
|
118
|
+
- **The idea**: for standard operations (GEMM, conv, FFT, sort, scan, reduce), a vendor-tuned primitive is usually far faster than a hand-written kernel and already applies coalescing/tiling/tensor-core tricks — call it instead of reinventing it.
|
|
119
|
+
- **Code signals**: a hand-written matmul/conv/sort/scan/reduce kernel; "I wrote my own GEMM"; standard ops reimplemented from scratch.
|
|
120
|
+
- **Speculative win**: large headroom — hand kernels for standard ops often reach only a fraction of the tuned library's throughput.
|
|
121
|
+
- **Cost / risk**: a dependency and an API to adopt; custom kernels can still win when fused with surrounding app-specific work; library shapes may not fit exactly.
|
|
122
|
+
- **Validate by**: benchmark the kernel against the library primitive (e.g. compare against cuBLAS / MPSMatrixMultiplication) for the same problem size.
|
|
123
|
+
|
|
124
|
+
### 13. Reconsider whether the GPU is the right tool at all
|
|
125
|
+
- **Borrowed from**: roofline + Amdahl reasoning; HPC offload practice.
|
|
126
|
+
- **The idea**: a GPU only wins when there is enough parallel, regular, arithmetic-heavy work to overcome transfer + launch overhead. Small, branchy, or transfer-bound work may be faster left on a well-vectorized CPU. Treat "offload to GPU" itself as a candidate to validate, not a default.
|
|
127
|
+
- **Code signals**: small inputs; irregular/pointer-chasing work; a port that copies more than it computes; low arithmetic intensity with frequent host sync.
|
|
128
|
+
- **Speculative win**: avoids a slower-than-CPU port; redirects effort to a lens that actually pays (CPU SIMD, locality, algorithmic).
|
|
129
|
+
- **Cost / risk**: needs an honest CPU baseline; the answer is workload-specific.
|
|
130
|
+
- **Validate by**: end-to-end GPU benchmark *including* transfer vs a tuned CPU baseline — profile via perf-design.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Idea Ranking — Perf-Scout
|
|
2
|
+
|
|
3
|
+
> How the orchestrator ranks candidate ideas in Phase 4 and scores each lens.
|
|
4
|
+
> This is a triage tool for **what to investigate first**, not a claim about
|
|
5
|
+
> realized gains. Nothing here asserts a speedup is real — the ranking sorts
|
|
6
|
+
> *hypotheses* by how worth-chasing they look.
|
|
7
|
+
|
|
8
|
+
## The three per-idea axes
|
|
9
|
+
|
|
10
|
+
Each scout already tags every idea on three axes. Use them as the inputs to the
|
|
11
|
+
priority tier.
|
|
12
|
+
|
|
13
|
+
| Axis | Question | Values |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **Leverage** | If this idea pans out, how big is the plausible upside? | High / Medium / Low |
|
|
16
|
+
| **Applicability** | How likely is it that this code actually fits the pattern? | Likely / Plausible / Speculative |
|
|
17
|
+
| **Cost** | How much work + risk to try it (implementation effort, correctness/behavior risk, memory tradeoff)? | Low / Medium / High |
|
|
18
|
+
|
|
19
|
+
Note the asymmetry: **Leverage** and **Applicability** are about *upside and fit*;
|
|
20
|
+
**Cost** is the *price of finding out*. A cheap experiment with uncertain payoff
|
|
21
|
+
can still rank high — the point is to surface what's worth a measurement.
|
|
22
|
+
|
|
23
|
+
## Priority tiers
|
|
24
|
+
|
|
25
|
+
Combine the axes into one of three tiers. The spirit: reward high plausible
|
|
26
|
+
upside and high fit, discount by cost/risk.
|
|
27
|
+
|
|
28
|
+
| Tier | Rough rule | Meaning |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| **Investigate-first** | High Leverage AND Applicability ≥ Plausible AND Cost ≤ Medium | Strong, well-located bet. Hand to perf-design to measure now. |
|
|
31
|
+
| **Worth-a-look** | (High Leverage with High Cost) OR (Medium Leverage with Applicability ≥ Plausible) | Real candidate; needs a closer look or a cheap experiment before committing. |
|
|
32
|
+
| **Long-shot** | Everything else — Low Leverage, or Speculative applicability, or High cost with modest upside | Keep on the deck for completeness; chase only if the obvious wins are exhausted. |
|
|
33
|
+
|
|
34
|
+
Two tie-breakers, in order:
|
|
35
|
+
1. **Cheaper-to-validate wins.** Between two same-tier ideas, rank the one that's
|
|
36
|
+
easier to confirm (a quick benchmark) above the one needing a big rewrite to
|
|
37
|
+
even test.
|
|
38
|
+
2. **Borrowed-from novelty.** A non-obvious idea from a different domain (a game
|
|
39
|
+
engine layout trick on a web service) ranks above a generic one of equal
|
|
40
|
+
tier — surfacing the unexpected is this skill's reason to exist.
|
|
41
|
+
|
|
42
|
+
## "Top 5 to investigate first"
|
|
43
|
+
|
|
44
|
+
After tiering, pick the five strongest Investigate-first ideas (fall through to
|
|
45
|
+
Worth-a-look if fewer than five qualify) for the report's headline callout and
|
|
46
|
+
the user summary. Spread them across lenses where possible — five ideas from one
|
|
47
|
+
lens is less useful than five angles from five domains.
|
|
48
|
+
|
|
49
|
+
## Lens opportunity-density score (0-10)
|
|
50
|
+
|
|
51
|
+
Score each lens for how much *plausible headroom* it surfaced. This is an
|
|
52
|
+
**opportunity** signal — high means "lots to chase here," NOT "the code is bad."
|
|
53
|
+
A low score is good news (little obvious headroom in that dimension).
|
|
54
|
+
|
|
55
|
+
| Score | Meaning |
|
|
56
|
+
|---|---|
|
|
57
|
+
| 0-2 | Lens barely applies, or only Long-shot ideas. Little headroom in this dimension. |
|
|
58
|
+
| 3-4 | A few Worth-a-look ideas; no strong bets. Modest headroom. |
|
|
59
|
+
| 5-6 | Several Worth-a-look or one Investigate-first. Real headroom worth a pass. |
|
|
60
|
+
| 7-8 | Multiple Investigate-first ideas, well-located. Rich headroom — prioritize this lens. |
|
|
61
|
+
| 9-10 | Many high-leverage, well-located, cheap-to-validate ideas. Exceptional headroom; likely the highest-value place to dig. |
|
|
62
|
+
|
|
63
|
+
There is **no overall code score** — unlike bug-scan, a high number here is an
|
|
64
|
+
invitation to investigate, not a verdict on quality. Report per-lens densities
|
|
65
|
+
and let the Top-5 callout carry the headline.
|
|
66
|
+
|
|
67
|
+
## Honesty guardrails
|
|
68
|
+
|
|
69
|
+
- Tiers rank *hypotheses*, not measured wins. The report and summary must keep
|
|
70
|
+
that framing: "ranked candidates to investigate," never "ranked improvements."
|
|
71
|
+
- An idea's tier can be high while its Applicability is Speculative — that's fine,
|
|
72
|
+
it just means "high upside if it fits, worth a quick check." Don't launder
|
|
73
|
+
Speculative into Likely to inflate the tier.
|
|
74
|
+
- If you can't articulate a validation path for an idea, it doesn't belong on the
|
|
75
|
+
deck at any tier — drop it.
|