From 6f6373d8d59f9010ea8ac1472841624f21d0b3d2 Mon Sep 17 00:00:00 2001 From: Jaime Camacho Date: Thu, 11 Sep 2025 18:00:58 +0200 Subject: [PATCH] =?UTF-8?q?Formatea=20m=C3=A9tricas=20como=20texto=20y=20d?= =?UTF-8?q?ocumenta=20columnas=20de=20an=C3=A1lisis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/3-Scenes/Main.unity | 4 +- Assets/ShaderBench/BenchmarkRunner.cs | 88 +++++++++++++++++---------- README.md | 11 ++++ 3 files changed, 70 insertions(+), 33 deletions(-) diff --git a/Assets/3-Scenes/Main.unity b/Assets/3-Scenes/Main.unity index 7e53120..1a18481 100644 --- a/Assets/3-Scenes/Main.unity +++ b/Assets/3-Scenes/Main.unity @@ -444,8 +444,8 @@ MonoBehaviour: uploadBatchSize: 32 newSheetPerRun: 1 sheetNamePrefix: Run_ - customRunLabel: - targetFPS: 60 + customRunLabel: + targetFPS: 72 --- !u!4 &1662094702 Transform: m_ObjectHideFlags: 0 diff --git a/Assets/ShaderBench/BenchmarkRunner.cs b/Assets/ShaderBench/BenchmarkRunner.cs index 86f6e51..fbf96e1 100644 --- a/Assets/ShaderBench/BenchmarkRunner.cs +++ b/Assets/ShaderBench/BenchmarkRunner.cs @@ -70,7 +70,7 @@ public enum CameraFitMode { Manual, AutoFitTopDownOrtho, AutoFitIsoPerspective } public string customRunLabel = ""; [Tooltip("FPS objetivo para análisis en Sheets (finalize)")] - public int targetFPS = 60; + public int targetFPS = 72; // Internos private string _currentSheetName; @@ -116,11 +116,14 @@ private class SheetRow public bool GPUInstancing, Shadows, ReceiveShadows; public string EnabledKW, DisabledKW; - public double CPU_ms_avg, CPU_ms_p95, CPU_ms_min, CPU_ms_max; - public double GPU_ms_avg, GPU_ms_p95, GPU_ms_min, GPU_ms_max; - public double FPS_avg, FPS_p95, FPS_min, FPS_max; + public string CPU_ms_avg, CPU_ms_p95, CPU_ms_min, CPU_ms_max; + public string GPU_ms_avg, GPU_ms_p95, GPU_ms_min, GPU_ms_max; + public string FPS_avg, FPS_p95, FPS_min, FPS_max; public string UnityVersion, RenderPipeline, GraphicsAPI, DeviceModel, OS; + public string Bottleneck; + public string Quest3Rating; + public string Summary; } [Serializable] @@ -288,7 +291,8 @@ void PrepareCSV(string path) "CPU_ms_avg", "CPU_ms_p95", "CPU_ms_min", "CPU_ms_max", "GPU_ms_avg", "GPU_ms_p95", "GPU_ms_min", "GPU_ms_max", "FPS_avg", "FPS_p95", "FPS_min", "FPS_max", - "UnityVersion", "RenderPipeline", "GraphicsAPI", "DeviceModel", "OS")); + "UnityVersion", "RenderPipeline", "GraphicsAPI", "DeviceModel", "OS", + "Bottleneck", "Quest3Rating", "Summary")); } catch (Exception e) { @@ -300,6 +304,7 @@ void AppendCSV(string path, BenchmarkCase c, int repetition, Stats s) { try { + AnalyzeStats(s, out string bottleneck, out string rating, out string summary); using var w = new StreamWriter(path, true); string rp = DetectRenderPipeline(); string gapi = SystemInfo.graphicsDeviceType.ToString(); @@ -315,26 +320,29 @@ void AppendCSV(string path, BenchmarkCase c, int repetition, Stats s) Escape(c.enabledKeywords), Escape(c.disabledKeywords), - s.cpuAvg.ToString("F4", CultureInfo.InvariantCulture), - s.cpuP95.ToString("F4", CultureInfo.InvariantCulture), - s.cpuMin.ToString("F4", CultureInfo.InvariantCulture), - s.cpuMax.ToString("F4", CultureInfo.InvariantCulture), + Math.Round(s.cpuAvg, 2).ToString("F2", CultureInfo.InvariantCulture), + Math.Round(s.cpuP95, 2).ToString("F2", CultureInfo.InvariantCulture), + Math.Round(s.cpuMin, 2).ToString("F2", CultureInfo.InvariantCulture), + Math.Round(s.cpuMax, 2).ToString("F2", CultureInfo.InvariantCulture), - s.gpuAvg.ToString("F4", CultureInfo.InvariantCulture), - s.gpuP95.ToString("F4", CultureInfo.InvariantCulture), - s.gpuMin.ToString("F4", CultureInfo.InvariantCulture), - s.gpuMax.ToString("F4", CultureInfo.InvariantCulture), + Math.Round(s.gpuAvg, 2).ToString("F2", CultureInfo.InvariantCulture), + Math.Round(s.gpuP95, 2).ToString("F2", CultureInfo.InvariantCulture), + Math.Round(s.gpuMin, 2).ToString("F2", CultureInfo.InvariantCulture), + Math.Round(s.gpuMax, 2).ToString("F2", CultureInfo.InvariantCulture), - s.fpsAvg.ToString("F2", CultureInfo.InvariantCulture), - s.fpsP95.ToString("F2", CultureInfo.InvariantCulture), - s.fpsMin.ToString("F2", CultureInfo.InvariantCulture), - s.fpsMax.ToString("F2", CultureInfo.InvariantCulture), + Math.Round(s.fpsAvg, 1).ToString("F1", CultureInfo.InvariantCulture), + Math.Round(s.fpsP95, 1).ToString("F1", CultureInfo.InvariantCulture), + Math.Round(s.fpsMin, 1).ToString("F1", CultureInfo.InvariantCulture), + Math.Round(s.fpsMax, 1).ToString("F1", CultureInfo.InvariantCulture), Escape(Application.unityVersion), Escape(rp), Escape(gapi), Escape(SystemInfo.deviceModel), - Escape(SystemInfo.operatingSystem))); + Escape(SystemInfo.operatingSystem), + Escape(bottleneck), + Escape(rating), + Escape(summary))); } catch (Exception e) { @@ -611,6 +619,8 @@ bool TryComputeRootBounds(out Bounds b) // =================== Google Sheets: helpers =================== private SheetRow BuildSheetRow(BenchmarkCase c, int rep, Stats s) { + AnalyzeStats(s, out string bottleneck, out string rating, out string summary); + return new SheetRow { Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), @@ -626,26 +636,42 @@ private SheetRow BuildSheetRow(BenchmarkCase c, int rep, Stats s) EnabledKW = c.enabledKeywords, DisabledKW = c.disabledKeywords, - CPU_ms_avg = s.cpuAvg, - CPU_ms_p95 = s.cpuP95, - CPU_ms_min = s.cpuMin, - CPU_ms_max = s.cpuMax, - GPU_ms_avg = s.gpuAvg, - GPU_ms_p95 = s.gpuP95, - GPU_ms_min = s.gpuMin, - GPU_ms_max = s.gpuMax, - FPS_avg = s.fpsAvg, - FPS_p95 = s.fpsP95, - FPS_min = s.fpsMin, - FPS_max = s.fpsMax, + CPU_ms_avg = Math.Round(s.cpuAvg, 2).ToString("F2", CultureInfo.InvariantCulture), + CPU_ms_p95 = Math.Round(s.cpuP95, 2).ToString("F2", CultureInfo.InvariantCulture), + CPU_ms_min = Math.Round(s.cpuMin, 2).ToString("F2", CultureInfo.InvariantCulture), + CPU_ms_max = Math.Round(s.cpuMax, 2).ToString("F2", CultureInfo.InvariantCulture), + GPU_ms_avg = Math.Round(s.gpuAvg, 2).ToString("F2", CultureInfo.InvariantCulture), + GPU_ms_p95 = Math.Round(s.gpuP95, 2).ToString("F2", CultureInfo.InvariantCulture), + GPU_ms_min = Math.Round(s.gpuMin, 2).ToString("F2", CultureInfo.InvariantCulture), + GPU_ms_max = Math.Round(s.gpuMax, 2).ToString("F2", CultureInfo.InvariantCulture), + FPS_avg = Math.Round(s.fpsAvg, 1).ToString("F1", CultureInfo.InvariantCulture), + FPS_p95 = Math.Round(s.fpsP95, 1).ToString("F1", CultureInfo.InvariantCulture), + FPS_min = Math.Round(s.fpsMin, 1).ToString("F1", CultureInfo.InvariantCulture), + FPS_max = Math.Round(s.fpsMax, 1).ToString("F1", CultureInfo.InvariantCulture), UnityVersion = Application.unityVersion, RenderPipeline = DetectRenderPipeline(), GraphicsAPI = SystemInfo.graphicsDeviceType.ToString(), DeviceModel = SystemInfo.deviceModel, - OS = SystemInfo.operatingSystem + OS = SystemInfo.operatingSystem, + Bottleneck = bottleneck, + Quest3Rating = rating, + Summary = summary }; } + + void AnalyzeStats(Stats s, out string bottleneck, out string rating, out string summary) + { + double frameBudget = 1000.0 / Mathf.Max(1, targetFPS); + double cpu = s.cpuP95; + double gpu = s.gpuP95; + bottleneck = cpu > gpu ? "CPU" : gpu > cpu ? "GPU" : "Balanced"; + double worst = Math.Max(cpu, gpu); + if (worst <= frameBudget) rating = "Good"; + else if (worst <= frameBudget * 1.5) rating = "Medium"; + else rating = "Bad"; + summary = $"{bottleneck} bottleneck - p95 {worst:F2}ms vs {frameBudget:F2}ms"; + } void EnqueueRow(SheetRow r) { _pendingRows.Add(r); diff --git a/README.md b/README.md index eb41885..9053222 100644 --- a/README.md +++ b/README.md @@ -46,3 +46,14 @@ Este proyecto incluye utilidades para medir rendimiento. Para Oculus Quest 3 es El script `QuestPerfLogger` guarda en `persistentDataPath/QuestPerf.csv` los tiempos de CPU/GPU y el nivel de batería. Añádelo a la escena principal para tener un HUD básico y un registro de datos durante las pruebas. +### Análisis automático en Google Sheets + +Los datos enviados a la hoja de cálculo ahora incluyen: + +- Valores de tiempo redondeados para facilitar la lectura. +- Detección del cuello de botella (CPU o GPU). +- Una valoración rápida sobre si el rendimiento es adecuado para Quest 3. +- Un campo de resumen con la comparación contra el presupuesto de tiempo de frame. + +Para que estos nuevos campos aparezcan en Google Sheets, actualiza el script de Apps Script añadiendo las columnas `Bottleneck`, `Quest3Rating` y `Summary` al arreglo `HEADERS`. +