Files
UniversalContainer/tools/analyze_large_comparison.ps1
T
Efim Beshmenev bbb43dbe57 Experiments
2026-08-11 23:35:38 +03:00

160 lines
6.5 KiB
PowerShell

param(
[Parameter(Mandatory = $true)]
[string]$InputDirectory
)
$ErrorActionPreference = 'Stop'
$invariant = [Globalization.CultureInfo]::InvariantCulture
[Threading.Thread]::CurrentThread.CurrentCulture = $invariant
[Threading.Thread]::CurrentThread.CurrentUICulture = $invariant
function ConvertTo-Number($Value) {
if ($Value -is [double] -or $Value -is [float] -or $Value -is [decimal]) {
return [double]$Value
}
$text = ([string]$Value).Trim()
if ($text.Contains(',') -and -not $text.Contains('.')) {
$text = $text.Replace(',', '.')
}
return [double]::Parse($text, [Globalization.NumberStyles]::Float, $invariant)
}
$directory = if ([IO.Path]::IsPathRooted($InputDirectory)) {
[IO.Path]::GetFullPath($InputDirectory)
} else {
[IO.Path]::GetFullPath((Join-Path (Resolve-Path '.').Path $InputDirectory))
}
$input = Join-Path $directory 'cell-medians-large.csv'
if (-not (Test-Path -LiteralPath $input -PathType Leaf)) {
throw "Missing cell medians: $input"
}
function Get-GeometricMean($Values) {
$positive = @($Values | Where-Object { (ConvertTo-Number $_) -gt 0 })
if ($positive.Count -eq 0) { return [double]::NaN }
$meanLog = ($positive | ForEach-Object {
[math]::Log((ConvertTo-Number $_))
} | Measure-Object -Average).Average
return [math]::Exp($meanLog)
}
$medians = @(Import-Csv -LiteralPath $input)
$comparisons = @($medians | Group-Object profile,type,workload,n | ForEach-Object {
$rows = @($_.Group)
$fixed = @($rows | Where-Object {
$_.structure -like 'tiered_forced_leaf_*'
} | Sort-Object { ConvertTo-Number $_.median_ns_per_op })
$adaptive = @($rows | Where-Object {
$_.structure -like 'adaptive_shape_deferred*'
})[0]
$vector = @($rows | Where-Object {
$_.structure -eq 'std::vector_reserved'
})[0]
if ($fixed.Count -ne 5 -or $null -eq $adaptive -or $null -eq $vector) {
throw "Incomplete seven-candidate cell: $($_.Name)"
}
$best = $fixed[0]
$ppmMatch = [regex]::Match($adaptive.workload, '_edit_ppm_(\d+)$')
if (-not $ppmMatch.Success) { throw "Invalid large workload: $($adaptive.workload)" }
$editPpm = [int]$ppmMatch.Groups[1].Value
$pattern = $adaptive.workload.Substring(
0, $adaptive.workload.Length - $ppmMatch.Value.Length)
$bestLeaf = [regex]::Match($best.structure, 'leaf_(\d+)').Groups[1].Value
$fixedNs = ConvertTo-Number $best.median_ns_per_op
$adaptiveNs = ConvertTo-Number $adaptive.median_ns_per_op
$vectorNs = ConvertTo-Number $vector.median_ns_per_op
[pscustomobject]@{
profile = $adaptive.profile
type = $adaptive.type
n = [long]$adaptive.n
pattern = $pattern
edit_ppm = $editPpm
workload = $adaptive.workload
best_fixed_leaf = [int]$bestLeaf
best_fixed_ns_per_op = $fixedNs
adaptive_ns_per_op = $adaptiveNs
vector_ns_per_op = $vectorNs
adaptive_over_best_fixed = $adaptiveNs / $fixedNs
vector_over_best_fixed = $vectorNs / $fixedNs
adaptive_over_vector = $adaptiveNs / $vectorNs
adaptive_switches = ConvertTo-Number $adaptive.median_switches
adaptive_leaf_rebuilds = ConvertTo-Number $adaptive.median_leaf_rebuilds
adaptive_final_mode = $adaptive.final_mode
adaptive_final_leaf = [int]$adaptive.final_leaf
adaptive_transition_ns = ConvertTo-Number $adaptive.median_max_transition_ns
adaptive_construction_ns = ConvertTo-Number $adaptive.median_construction_ns
vector_construction_ns = ConvertTo-Number $vector.median_construction_ns
best_fixed_construction_ns = ConvertTo-Number $best.median_construction_ns
}
})
$comparisons | Sort-Object n,pattern,edit_ppm,profile |
Export-Csv -LiteralPath (Join-Path $directory 'comparison-large.csv') `
-NoTypeInformation -Encoding utf8
$bySize = @($comparisons | Group-Object n | ForEach-Object {
$cells = @($_.Group)
[pscustomobject]@{
n = [long]$cells[0].n
cells = $cells.Count
gm_adaptive_over_best_fixed = Get-GeometricMean $cells.adaptive_over_best_fixed
gm_vector_over_best_fixed = Get-GeometricMean $cells.vector_over_best_fixed
gm_adaptive_over_vector = Get-GeometricMean $cells.adaptive_over_vector
adaptive_beats_best_fixed = @($cells | Where-Object {
$_.adaptive_over_best_fixed -lt 1
}).Count
adaptive_beats_vector = @($cells | Where-Object {
$_.adaptive_over_vector -lt 1
}).Count
adaptive_final_vector = @($cells | Where-Object {
$_.adaptive_final_mode -eq 'vector'
}).Count
adaptive_final_tiered = @($cells | Where-Object {
$_.adaptive_final_mode -eq 'tiered'
}).Count
}
})
$bySize | Sort-Object n | Export-Csv `
-LiteralPath (Join-Path $directory 'comparison-by-size.csv') `
-NoTypeInformation -Encoding utf8
$byWorkload = @($comparisons | Group-Object n,pattern,edit_ppm | ForEach-Object {
$cells = @($_.Group)
[pscustomobject]@{
n = [long]$cells[0].n
pattern = $cells[0].pattern
edit_ppm = [int]$cells[0].edit_ppm
profiles = $cells.Count
best_fixed_leaf_mode = ($cells | Group-Object best_fixed_leaf |
Sort-Object Count -Descending | Select-Object -First 1).Name
gm_adaptive_over_best_fixed = Get-GeometricMean $cells.adaptive_over_best_fixed
gm_vector_over_best_fixed = Get-GeometricMean $cells.vector_over_best_fixed
gm_adaptive_over_vector = Get-GeometricMean $cells.adaptive_over_vector
mean_switches = ($cells.adaptive_switches | Measure-Object -Average).Average
mean_leaf_rebuilds = ($cells.adaptive_leaf_rebuilds | Measure-Object -Average).Average
final_modes = (($cells.adaptive_final_mode | Group-Object | ForEach-Object {
"$($_.Name):$($_.Count)"
}) -join ';')
}
})
$byWorkload | Sort-Object n,pattern,edit_ppm | Export-Csv `
-LiteralPath (Join-Path $directory 'comparison-by-workload.csv') `
-NoTypeInformation -Encoding utf8
$winners = @($comparisons | Group-Object best_fixed_leaf | ForEach-Object {
[pscustomobject]@{
leaf = [int]$_.Name
wins = $_.Count
percent = 100.0 * $_.Count / $comparisons.Count
}
})
$winners | Sort-Object wins -Descending | Export-Csv `
-LiteralPath (Join-Path $directory 'fixed-leaf-winners.csv') `
-NoTypeInformation -Encoding utf8
Write-Host "Large comparison analysis: $directory"
$bySize | Sort-Object n | Format-Table -AutoSize
$winners | Sort-Object wins -Descending | Format-Table -AutoSize