-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rebuilding site Wed, Aug 21, 2024 8:24:43 PM
- Loading branch information
Showing
2 changed files
with
387 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,382 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<!-- | ||
SPDX-FileCopyrightText: 2024 Erin Catto | ||
SPDX-License-Identifier: MIT --> | ||
|
||
<!-- https://cdn.jsdelivr.net/gh/erincatto/box2c@main/benchmark/amd7950x/joint_grid.csv --> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Box2D Benchmarks</title> | ||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"></script> | ||
|
||
<style> | ||
body { | ||
background-color: #181818; | ||
color: #e0e0e0; | ||
font-family: Arial, sans-serif; | ||
} | ||
select, button { | ||
background-color: #333; | ||
color: #e0e0e0; | ||
border: 1px solid #555; | ||
padding: 5px 10px; | ||
margin: 5px; | ||
} | ||
.chart-container { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
gap: 30px; | ||
max-width: 1000px; | ||
margin: 0 auto; | ||
} | ||
.chart-item { | ||
width: 100%; | ||
height: 700px; /* Fixed height for each chart */ | ||
} | ||
canvas { | ||
background-color: #1e1e1e; | ||
border: 1px solid #333; | ||
} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<h1>Box2D Benchmarks</h1> | ||
|
||
Platforms tested: | ||
<ul> | ||
<li>AVX2 : AMD 7950X</li> | ||
<li>SSE2 : AMD 7950X</li> | ||
<li>scalar : AMD 7950X</li> | ||
<li>Neon : Apple M2</li> | ||
</ul> | ||
|
||
<hr/> | ||
|
||
<label for="branchSelect">Compare Branch:</label> | ||
<select id="branchSelect"> | ||
<option value="">Loading branches...</option> | ||
</select> | ||
|
||
<button id="loadButton">Load</button> | ||
|
||
<div class="chart-container"> | ||
<img src="/images/joint_grid_benchmark.png" width="640" height="360"> | ||
<div class="chart-item"> | ||
<canvas id="joint_grid"></canvas> | ||
</div> | ||
<img src="/images/large_pyramid_benchmark.png" width="640" height="360"> | ||
<div class="chart-item"> | ||
<canvas id="large_pyramid"></canvas> | ||
</div> | ||
<img src="/images/many_pyramids_benchmark.png" width="640" height="360"> | ||
<div class="chart-item"> | ||
<canvas id="many_pyramids"></canvas> | ||
</div> | ||
<img src="/images/smash_benchmark.png" width="640" height="360"> | ||
<div class="chart-item"> | ||
<canvas id="smash"></canvas> | ||
</div> | ||
<img src="/images/tumbler_benchmark.png" width="640" height="360"> | ||
<div class="chart-item"> | ||
<canvas id="tumbler"></canvas> | ||
</div> | ||
</div> | ||
|
||
<script> | ||
const repoBaseUrl = 'https://raw.githubusercontent.com/erincatto/box2d'; | ||
|
||
const benchmarks = [ | ||
{ | ||
label: 'Joint Grid', | ||
id: 'joint_grid', | ||
description: '10k Circles, 19800 Revolute Joints', | ||
chart: null | ||
}, | ||
{ | ||
label: 'Large Pyramid', | ||
id: 'large_pyramid', | ||
description: '5050 boxes', | ||
chart: null | ||
}, | ||
{ | ||
label: 'Many Pyramids', | ||
id: 'many_pyramids', | ||
description: '400 Pyramids with 55 Boxes Each', | ||
chart: null | ||
}, | ||
{ | ||
label: 'Smash', | ||
id: 'smash', | ||
description: 'Large Box Colliding with 9600 Small Boxes', | ||
chart: null | ||
}, | ||
{ | ||
label: 'Tumbler', | ||
id: 'tumbler', | ||
description: '2026 Small Boxes Tumbling in a Large Hollow Box', | ||
chart: null | ||
} | ||
]; | ||
|
||
const processors = [ | ||
{ | ||
folder: 'amd7950x', | ||
label: 'avx2' | ||
}, | ||
{ | ||
folder: 'm2air', | ||
label: 'neon' | ||
}, | ||
{ | ||
folder: 'amd7950x_sse2', | ||
label: 'sse2', | ||
}, | ||
{ | ||
|
||
folder: 'amd7950x_float', | ||
label: 'scalar' | ||
} | ||
]; | ||
|
||
const branchSelect = document.getElementById('branchSelect'); | ||
const loadButton = document.getElementById('loadButton'); | ||
var currentBranch = null; | ||
|
||
async function fetchCSV(url) { | ||
const response = await fetch(url); | ||
return response.text(); | ||
} | ||
|
||
async function fetchBranches() { | ||
const url = `https://api.github.com/repos/erincatto/box2d/branches`; | ||
const response = await fetch(url); | ||
if (!response.ok) { | ||
throw new Error(`HTTP error! status: ${response.status}`); | ||
} | ||
return response.json(); | ||
} | ||
|
||
async function populateBranches() { | ||
try { | ||
const branches = await fetchBranches(); | ||
|
||
// Clear existing options | ||
branchSelect.innerHTML = ''; | ||
|
||
branches.forEach(branch => { | ||
if (branch.name != 'main') | ||
{ | ||
const option = document.createElement('option'); | ||
option.value = branch.name; | ||
option.textContent = branch.name; | ||
branchSelect.appendChild(option); | ||
|
||
if (currentBranch == null) | ||
{ | ||
currentBranch = branch.name; | ||
} | ||
} | ||
}); | ||
|
||
} catch (error) { | ||
console.error('Error fetching branches:', error); | ||
branchSelect.innerHTML = '<option value="">Error loading branches</option>'; | ||
} | ||
} | ||
|
||
async function loadData(branches, benchmark) | ||
{ | ||
const datasets = []; | ||
|
||
var file = benchmark.id + '.csv'; | ||
|
||
for (const branch of branches) | ||
{ | ||
for (const processor of processors) | ||
{ | ||
const csvUrl = repoBaseUrl + '/' + branch + '/benchmark/' + processor.folder + '/' + file; | ||
|
||
try | ||
{ | ||
const csv = await fetchCSV(csvUrl); | ||
const csvResult = Papa.parse(csv, {header: true, skipEmptyLines: true}); | ||
const data = csvResult.data; | ||
|
||
if (data != null) | ||
{ | ||
if (branch == 'main') | ||
{ | ||
datasets.push({ | ||
label: processor.label, | ||
|
||
// convert the csv data into chart ready data | ||
data: data.map(row => ({ x: row.threads, y: 1000.0 / row.fps })), | ||
fill: false | ||
}); | ||
} | ||
else | ||
{ | ||
// remove leading name from branch name (e.g. erincatto) | ||
const branchLabel = branch.split('/').pop(); | ||
|
||
datasets.push({ | ||
label: processor.label + '/' + branchLabel, | ||
|
||
// convert the csv data into chart ready data | ||
data: data.map(row => ({ x: row.threads, y: row.fps })), | ||
|
||
borderDash: [5, 5], | ||
fill: false | ||
}); | ||
} | ||
} | ||
} | ||
catch (error) { | ||
console.error(`Error loading the CSV file (${csvUrl}):`, error); | ||
throw new Error('Failed to load the CSV file. It may be missing or inaccessible.'); | ||
} | ||
} | ||
} | ||
|
||
return {datasets: datasets, benchmark: benchmark}; | ||
} | ||
|
||
async function createChart(datasets, benchmark) | ||
{ | ||
// get the document element for this benchmark | ||
const ctx = document.getElementById(benchmark.id).getContext('2d'); | ||
|
||
if (benchmark.chart) | ||
{ | ||
// Destroy the previous chart if it exists | ||
benchmark.chart.destroy(); | ||
benchmark.chart = null; | ||
} | ||
|
||
if (datasets == null) | ||
{ | ||
return; | ||
} | ||
|
||
benchmark.chart = new Chart(ctx, | ||
{ | ||
type: 'line', | ||
data: { datasets }, | ||
options: { | ||
responsive: true, | ||
maintainAspectRatio: false, | ||
layout: { | ||
padding: { | ||
left: 10, | ||
right: 20, | ||
top: 10, | ||
bottom: 10 | ||
} | ||
}, | ||
plugins: { | ||
title: { | ||
display: true, | ||
text: benchmark.label + ': ' + benchmark.description, | ||
color: '#e0e0e0' | ||
}, | ||
legend: { | ||
display: true, | ||
labels: { | ||
color: '#e0e0e0' | ||
} | ||
}, | ||
}, | ||
scales: { | ||
x: { | ||
title: | ||
{ | ||
display: true, | ||
text: 'threads', | ||
color: '#e0e0e0' | ||
}, | ||
type: 'linear', | ||
position: 'bottom', | ||
grid: { | ||
color: '#333' | ||
}, | ||
ticks: { | ||
color: '#e0e0e0' | ||
} | ||
}, | ||
y: { | ||
title: | ||
{ | ||
display: true, | ||
text: 'ms', | ||
color: '#e0e0e0' | ||
}, | ||
grid: { | ||
color: '#333' | ||
}, | ||
ticks: { | ||
color: '#e0e0e0' | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
|
||
async function createCharts() | ||
{ | ||
const branches = ['main']; | ||
|
||
if (currentBranch != null) | ||
{ | ||
branches.push(currentBranch); | ||
} | ||
|
||
const dataPromises = []; | ||
for (const benchmark of benchmarks) | ||
{ | ||
dataPromises.push(loadData(branches, benchmark)); | ||
} | ||
|
||
Promise.all(dataPromises).then((values) => | ||
{ | ||
for (value of values) | ||
{ | ||
createChart(value.datasets, value.benchmark); | ||
} | ||
}); | ||
} | ||
|
||
// connect button listener | ||
loadButton.addEventListener('click', async () => { | ||
|
||
if (branchSelect.value == null) | ||
{ | ||
alert('No branch selected'); | ||
} | ||
else | ||
{ | ||
try { | ||
currentBranch = branchSelect.value; | ||
await createCharts(); | ||
} | ||
catch (error) { | ||
// failed to load data | ||
alert(error.message); | ||
} | ||
} | ||
}); | ||
|
||
Chart.defaults.font.size = 14; | ||
createCharts().then(populateBranches()); | ||
|
||
</script> | ||
</body> | ||
|
||
</html> |
Oops, something went wrong.