degradation-comparison/render-farm-capacity-planner.html
2026-07-18 19:32:55 +00:00

138 lines
6.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Capacity Planner | stream.4ort.net</title>
<style>
:root { --bg:#050505; --fg:#e0e0e0; --accent:#7aa2f7; --dim:#404040; --border:#1a1a1a; }
* { box-sizing:border-box; }
body { background:var(--bg); color:var(--fg); font-family:system-ui,sans-serif; margin:0; padding:3rem; line-height:1.6; }
.wrap { max-width:1100px; margin:0 auto; display:grid; grid-template-columns:1fr 400px; gap:3rem; }
h1 { font-size:2.2rem; letter-spacing:-0.03em; margin:0 0 1rem 0; }
h2 { font-size:0.75rem; opacity:0.5; font-family:monospace; margin:2rem 0 1rem 0; text-transform:uppercase; letter-spacing:0.12em; }
a { color:var(--accent); text-decoration:none; border-bottom:1px solid var(--border); }
.card { border:1px solid var(--border); padding:1.5rem; background:#080808; }
.input-group { margin-bottom:1rem; }
label { display:block; font-size:0.75rem; opacity:0.7; margin-bottom:0.3rem; font-family:monospace; }
input[type="number"] { width:100%; background:#0a0a0a; border:1px solid var(--dim); color:var(--fg); padding:0.6rem; font-family:monospace; font-size:0.9rem; }
input:focus { outline:none; border-color:var(--accent); }
.output { background:#0a0a0a; border:1px solid var(--accent); padding:1rem; font-family:monospace; font-size:0.85rem; white-space:pre-wrap; }
.metric { display:flex; justify-content:space-between; padding:0.4rem 0; border-bottom:1px dashed var(--dim); }
.metric:last-child { border-bottom:none; }
.metric-label { opacity:0.6; }
.metric-val { font-weight:bold; color:var(--accent); }
img { width:100%; height:auto; filter:contrast(1.1) brightness(0.9); }
.note { font-size:0.75rem; opacity:0.5; margin-top:1rem; font-style:italic; }
.formula { background:#0a0a0a; padding:1rem; font-family:monospace; font-size:0.8rem; border-left:3px solid var(--accent); margin:1.5rem 0; }
</style>
<script defer src="https://analytics.4ort.xyz/script.js" data-website-id="d3ed927c-888a-4a6c-ae5f-0b1c613ddf5b"></script>
</head>
<body>
<div class="wrap">
<main>
<h1>Capacity Planner</h1>
<p>FIFA 2026 requires 16 venues, 104 matches, 60 days of continuous operation. This planner computes the GPU-hours required to render all broadcast assets before kickoff.</p>
<div class="formula">
CAPACITY = V × M × A × R ÷ S<br>
where:<br>
&nbsp;&nbsp;V = venues (16)<br>
&nbsp;&nbsp;M = matches per venue (avg 6.5)<br>
&nbsp;&nbsp;A = assets per match (3200 frames × 8 cameras = 25,600)<br>
&nbsp;&nbsp;R = resolution factor (8K = 33.2M px vs 1080p baseline = 2.1M → ×15.8)<br>
&nbsp;&nbsp;S = single-GPU render speed (frames/sec)
</div>
<h2>Grounded Data</h2>
<p>Source: <a href="https://4ort.xyz/entity/2026-fifa-world-cup" target="_blank">Wikidata Q5020214</a> — 2026 FIFA World Cup hosted across United States, Mexico, and Canada. Venue list includes Arrowhead Stadium, AT&T Stadium, BC Place, BMO Field, Estadio Akron, NRG Stadium, SoFi Stadium, Levi's Stadium, and 8 additional sites.</p>
<p>Pipeline precedent: <a href="render-farm-theory.html">Theory page</a> establishes throughput as T⁻¹. <a href="render-farm-calculator.html">Calculator</a> implements T = N × (F ÷ S) × 3600.</p>
<h2>Why This Matters</h2>
<p>Broadcast deadlines are absolute. A frame late means a blackout. The planner below takes venue count, match distribution, asset complexity, and hardware spec to output:</p>
<ul>
<li>Total GPU-hours required</li>
<li>Minimum cluster size for 60-day runway</li>
<li>Critical path bottleneck</li>
</ul>
<img src="https://images.pexels.com/photos/37730212/pexels-photo-37730212.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Data center server racks with active equipment">
<p class="note">Image: Pexels (CC0). Server density represents minimum cluster footprint.</p>
</main>
<aside class="card">
<h2>Inputs</h2>
<div class="input-group">
<label>Venues</label>
<input type="number" id="venues" value="16" min="1">
</div>
<div class="input-group">
<label>Matches per venue (avg)</label>
<input type="number" id="matchesPerVenue" value="6.5" step="0.5">
</div>
<div class="input-group">
<label>Assets per match (frames × cameras)</label>
<input type="number" id="assetsPerMatch" value="25600">
</div>
<div class="input-group">
<label>Resolution multiplier (8K vs 1080p)</label>
<input type="number" id="resolutionMult" value="15.8" step="0.1">
</div>
<div class="input-group">
<label>GPU render speed (frames/sec)</label>
<input type="number" id="gpuSpeed" value="120" step="1">
</div>
<div class="input-group">
<label>Available hours (60 days)</label>
<input type="number" id="availableHours" value="1440">
</div>
<button onclick="compute()" style="width:100%; padding:0.8rem; background:var(--accent); color:#000; border:none; font-weight:bold; cursor:pointer; margin-top:1rem;">COMPUTE</button>
<div class="output" id="results" style="margin-top:1.5rem;"></div>
</aside>
</div>
<script>
function compute() {
const V = parseFloat(document.getElementById('venues').value) || 16;
const M = parseFloat(document.getElementById('matchesPerVenue').value) || 6.5;
const A = parseFloat(document.getElementById('assetsPerMatch').value) || 25600;
const R = parseFloat(document.getElementById('resolutionMult').value) || 15.8;
const S = parseFloat(document.getElementById('gpuSpeed').value) || 120;
const H = parseFloat(document.getElementById('availableHours').value) || 1440;
const totalFrames = V * M * A * R;
const gpuHoursRequired = totalFrames / (S * 3600);
const gpusRequired = Math.ceil(gpuHoursRequired / H);
const headroom = ((H * gpusRequired - gpuHoursRequired) / gpuHoursRequired * 100).toFixed(1);
const results = `CAPACITY PLAN — FIFA 2026
━━━━━━━━━━━━━━━━━━━━━━
Total Frames to Render: ${totalFrameString(totalFrames)}
GPU-Hours Required: ${(gpuHoursRequired/1e6).toFixed(2)}M
Minimum Cluster Size: ${gpusRequired} GPUs
Headroom at 60 Days: ${headroom}%
CRITICAL PATH:
• Asset generation: ${((V*M*A)/1e6).toFixed(2)}M base frames
• Resolution upscale: ×${R}
• Parallelization ceiling: ${gpusRequired} nodes`;
document.getElementById('results').textContent = results;
}
function totalFrameString(n) {
if (n >= 1e9) return (n/1e9).toFixed(2) + 'B';
if (n >= 1e6) return (n/1e6).toFixed(2) + 'M';
if (n >= 1e3) return (n/1e3).toFixed(2) + 'K';
return n.toString();
}
compute();
</script>
</body>
</html>