updated ChunkMark

This commit is contained in:
Stan44 2025-05-10 03:03:39 -05:00
parent becedccadd
commit f35c612019

View File

@ -1,4 +1,5 @@
using System; using System;
using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -159,6 +160,9 @@ namespace ChunkMark
} }
PrintSummary(); PrintSummary();
PrintDetailedChunkInfo();
// Save benchmark results to log file
SaveBenchmarkLog();
Console.ForegroundColor = _infoColor; // Using _infoColor here Console.ForegroundColor = _infoColor; // Using _infoColor here
Console.WriteLine("\nDone. Press any key to exit."); Console.WriteLine("\nDone. Press any key to exit.");
@ -196,10 +200,11 @@ namespace ChunkMark
return; return;
} }
// Standard benchmark results table
var table = new StringBuilder(); var table = new StringBuilder();
table.AppendLine("┌────────────────┬─────────────┬────────────┬────────────┬────────────┐"); table.AppendLine("┌────────────────┬─────────────┬────────────┬────────────┬────────────┬────────────┐");
table.AppendLine("│ Test │ Chunks │ Create │ Access │ Unload │"); table.AppendLine("│ Test │ Chunks │ Create │ Access │ Unload │ Memory │");
table.AppendLine("├────────────────┼─────────────┼────────────┼────────────┼────────────┤"); table.AppendLine("├────────────────┼─────────────┼────────────┼────────────┼────────────┼────────────┤");
foreach (var result in _results) foreach (var result in _results)
{ {
@ -208,11 +213,12 @@ namespace ChunkMark
string createTime = $"{result.CreateTime:F3} s".PadRight(10).Substring(0, 10); string createTime = $"{result.CreateTime:F3} s".PadRight(10).Substring(0, 10);
string accessTime = $"{result.AccessTime:F3} s".PadRight(10).Substring(0, 10); string accessTime = $"{result.AccessTime:F3} s".PadRight(10).Substring(0, 10);
string unloadTime = $"{result.UnloadTime:F3} s".PadRight(10).Substring(0, 10); string unloadTime = $"{result.UnloadTime:F3} s".PadRight(10).Substring(0, 10);
string memoryUsed = FormatByteSize(result.MemoryUsed).PadRight(10).Substring(0, 10);
table.AppendLine($"│ {testName} │ {chunkInfo} │ {createTime} │ {accessTime} │ {unloadTime} │"); table.AppendLine($"│ {testName} │ {chunkInfo} │ {createTime} │ {accessTime} │ {unloadTime} │ {memoryUsed} │");
} }
table.AppendLine("└────────────────┴─────────────┴────────────┴────────────┴────────────┘"); table.AppendLine("└────────────────┴─────────────┴────────────┴────────────┴────────────┴────────────┘");
Console.WriteLine(table.ToString()); Console.WriteLine(table.ToString());
// Calculate and display performance metrics // Calculate and display performance metrics
@ -224,12 +230,71 @@ namespace ChunkMark
var create2DRate = _results.Where(r => r.TestName.Contains("2D")).Select(r => r.ChunkCount / r.CreateTime).FirstOrDefault(); var create2DRate = _results.Where(r => r.TestName.Contains("2D")).Select(r => r.ChunkCount / r.CreateTime).FirstOrDefault();
var create3DRate = _results.Where(r => r.TestName.Contains("3D")).Select(r => r.ChunkCount / r.CreateTime).FirstOrDefault(); var create3DRate = _results.Where(r => r.TestName.Contains("3D")).Select(r => r.ChunkCount / r.CreateTime).FirstOrDefault();
var access2DRate = _results.Where(r => r.TestName.Contains("2D")).Select(r => r.ChunkCount / r.AccessTime).FirstOrDefault();
var access3DRate = _results.Where(r => r.TestName.Contains("3D")).Select(r => r.ChunkCount / r.AccessTime).FirstOrDefault();
if (create2DRate > 0) if (create2DRate > 0)
Console.WriteLine($"2D Chunk Creation Rate: {create2DRate:N0} chunks/second"); Console.WriteLine($"2D Chunk Creation Rate: {create2DRate:N0} chunks/second");
if (create3DRate > 0) if (create3DRate > 0)
Console.WriteLine($"3D Chunk Creation Rate: {create3DRate:N0} chunks/second"); Console.WriteLine($"3D Chunk Creation Rate: {create3DRate:N0} chunks/second");
if (access2DRate > 0)
Console.WriteLine($"2D Chunk Access Rate: {access2DRate:N0} chunks/second");
if (access3DRate > 0)
Console.WriteLine($"3D Chunk Access Rate: {access3DRate:N0} chunks/second");
} }
// Memory usage summary
Console.ForegroundColor = _memoryColor;
Console.WriteLine("\nMemory Usage Summary:");
Console.ResetColor();
var memoryReport = AdvChkSys.AdvChkSys.GetMemoryUsage();
Console.WriteLine($"Current Memory Usage: {FormatByteSize(memoryReport.EstimatedChunkMemoryBytes)}");
Console.WriteLine($"Active Chunks: {memoryReport.ActiveChunkCount:N0}");
Console.WriteLine($"Available System Memory: {FormatByteSize(memoryReport.AvailableSystemMemoryBytes)}");
Console.WriteLine($"Memory Usage: {memoryReport.MemoryUsagePercentage:F2}% of total system memory");
// System information
Console.ForegroundColor = _headerColor;
Console.WriteLine("\nSystem Information:");
Console.ResetColor();
Console.WriteLine($"CPU Threads: {Environment.ProcessorCount}");
Console.WriteLine($"Total System Memory: {FormatByteSize(memoryReport.TotalSystemMemoryBytes)}");
Console.WriteLine($"AdvChkSys Version: {AdvChkSys.AdvChkSys.Version}");
// Memory efficiency metrics
if (_results.Count > 0)
{
var result2D = _results.FirstOrDefault(r => r.TestName.Contains("2D"));
var result3D = _results.FirstOrDefault(r => r.TestName.Contains("3D"));
if (result2D != null && result2D.ChunkCount > 0)
{
ulong bytesPerChunk2D = result2D.MemoryUsed / (ulong)result2D.ChunkCount;
Console.WriteLine($"2D Memory Efficiency: {FormatByteSize(bytesPerChunk2D)}/chunk");
}
if (result3D != null && result3D.ChunkCount > 0)
{
ulong bytesPerChunk3D = result3D.MemoryUsed / (ulong)result3D.ChunkCount;
Console.WriteLine($"3D Memory Efficiency: {FormatByteSize(bytesPerChunk3D)}/chunk");
}
}
// If stress test was run, show its results
var stressResult = _results.FirstOrDefault(r => r.TestName.Contains("Stress"));
if (stressResult != null)
{
Console.ForegroundColor = _headerColor;
Console.WriteLine("\nStress Test Results:");
Console.ResetColor();
Console.WriteLine($"Chunks Processed: {stressResult.ChunkCount:N0}");
Console.WriteLine($"Processing Time: {stressResult.CreateTime:F2} seconds");
Console.WriteLine($"Processing Rate: {stressResult.ChunkCount / stressResult.CreateTime:N0} chunks/second");
Console.WriteLine($"Peak Memory Usage: {FormatByteSize(stressResult.MemoryUsed)}");
}
} }
private static void Benchmark2D(int cpuCount, int numChunks, int chunkSize, int maxLoaded) private static void Benchmark2D(int cpuCount, int numChunks, int chunkSize, int maxLoaded)
@ -705,6 +770,146 @@ namespace ChunkMark
return $"{formattedSize:F2} {sizes[order]}"; return $"{formattedSize:F2} {sizes[order]}";
} }
private static void SaveBenchmarkLog()
{
// Create logs directory if it doesn't exist
string logsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
Directory.CreateDirectory(logsDirectory);
// Generate a unique filename with timestamp
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string logFileName = $"ChunkMark_{timestamp}.log";
string logFilePath = Path.Combine(logsDirectory, logFileName);
// Create a string builder to hold the log content
var logContent = new StringBuilder();
// Add header
logContent.AppendLine("=================================================================");
logContent.AppendLine($"ChunkMark Benchmark Results - {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
logContent.AppendLine("=================================================================");
logContent.AppendLine();
// Add system information
var memoryReport = AdvChkSys.AdvChkSys.GetMemoryUsage();
logContent.AppendLine("System Information:");
logContent.AppendLine($"CPU Threads: {Environment.ProcessorCount}");
logContent.AppendLine($"Total System Memory: {FormatByteSize(memoryReport.TotalSystemMemoryBytes)}");
logContent.AppendLine($"Available System Memory: {FormatByteSize(memoryReport.AvailableSystemMemoryBytes)}");
logContent.AppendLine($"AdvChkSys Version: {AdvChkSys.AdvChkSys.Version}");
logContent.AppendLine();
// Add benchmark results
logContent.AppendLine("Benchmark Results:");
logContent.AppendLine("------------------------------------------------------------------");
if (_results.Count == 0)
{
logContent.AppendLine("No benchmark results to display.");
}
else
{
// Header row
logContent.AppendLine(
$"{"Test",-15} | {"Chunks",-10} | {"Size",-12} | {"Create (s)",-10} | {"Access (s)",-10} | {"Unload (s)",-10} | {"Memory",-12}");
logContent.AppendLine(new string('-', 90));
// Data rows
foreach (var result in _results)
{
logContent.AppendLine(
$"{result.TestName,-15} | {result.ChunkCount,-10:N0} | {result.ChunkSize,-12} | " +
$"{result.CreateTime,-10:F3} | {result.AccessTime,-10:F3} | {result.UnloadTime,-10:F3} | " +
$"{FormatByteSize(result.MemoryUsed),-12}");
}
}
logContent.AppendLine();
// Add performance metrics
logContent.AppendLine("Performance Metrics:");
logContent.AppendLine("------------------------------------------------------------------");
if (_results.Count > 0)
{
var create2DRate = _results.Where(r => r.TestName.Contains("2D")).Select(r => r.ChunkCount / r.CreateTime).FirstOrDefault();
var create3DRate = _results.Where(r => r.TestName.Contains("3D")).Select(r => r.ChunkCount / r.CreateTime).FirstOrDefault();
var access2DRate = _results.Where(r => r.TestName.Contains("2D")).Select(r => r.ChunkCount / r.AccessTime).FirstOrDefault();
var access3DRate = _results.Where(r => r.TestName.Contains("3D")).Select(r => r.ChunkCount / r.AccessTime).FirstOrDefault();
if (create2DRate > 0)
logContent.AppendLine($"2D Chunk Creation Rate: {create2DRate:N0} chunks/second");
if (create3DRate > 0)
logContent.AppendLine($"3D Chunk Creation Rate: {create3DRate:N0} chunks/second");
if (access2DRate > 0)
logContent.AppendLine($"2D Chunk Access Rate: {access2DRate:N0} chunks/second");
if (access3DRate > 0)
logContent.AppendLine($"3D Chunk Access Rate: {access3DRate:N0} chunks/second");
}
logContent.AppendLine();
// Add memory usage summary
logContent.AppendLine("Memory Usage Summary:");
logContent.AppendLine("------------------------------------------------------------------");
logContent.AppendLine($"Current Memory Usage: {FormatByteSize(memoryReport.EstimatedChunkMemoryBytes)}");
logContent.AppendLine($"Active Chunks: {memoryReport.ActiveChunkCount:N0}");
logContent.AppendLine($"Memory Usage: {memoryReport.MemoryUsagePercentage:F2}% of total system memory");
// Memory efficiency metrics
if (_results.Count > 0)
{
var result2D = _results.FirstOrDefault(r => r.TestName.Contains("2D"));
var result3D = _results.FirstOrDefault(r => r.TestName.Contains("3D"));
if (result2D != null && result2D.ChunkCount > 0)
{
ulong bytesPerChunk2D = result2D.MemoryUsed / (ulong)result2D.ChunkCount;
logContent.AppendLine($"2D Memory Efficiency: {FormatByteSize(bytesPerChunk2D)}/chunk");
}
if (result3D != null && result3D.ChunkCount > 0)
{
ulong bytesPerChunk3D = result3D.MemoryUsed / (ulong)result3D.ChunkCount;
logContent.AppendLine($"3D Memory Efficiency: {FormatByteSize(bytesPerChunk3D)}/chunk");
}
}
// Write the log to file
File.WriteAllText(logFilePath, logContent.ToString());
Console.ForegroundColor = _infoColor;
Console.WriteLine($"\nBenchmark results saved to: {logFilePath}");
Console.ResetColor();
}
private static void PrintDetailedChunkInfo()
{
Console.ForegroundColor = _headerColor;
Console.WriteLine("\nDetailed Chunk Information:");
Console.ResetColor();
var memoryReport = AdvChkSys.AdvChkSys.GetMemoryUsage();
Console.WriteLine($"Active Chunks (reported by ChunkResourceManager): {memoryReport.ActiveChunkCount:N0}");
// Get counts from results
int total2DChunks = _results.Where(r => r.TestName.Contains("2D")).Sum(r => r.ChunkCount);
int total3DChunks = _results.Where(r => r.TestName.Contains("3D")).Sum(r => r.ChunkCount);
int totalChunks = total2DChunks + total3DChunks;
Console.WriteLine($"Total 2D Chunks Created: {total2DChunks:N0}");
Console.WriteLine($"Total 3D Chunks Created: {total3DChunks:N0}");
Console.WriteLine($"Total Chunks Created: {totalChunks:N0}");
if (memoryReport.ActiveChunkCount != totalChunks)
{
Console.ForegroundColor = _infoColor;
Console.WriteLine("\nPossible reasons for the difference:");
Console.WriteLine("1. Chunk eviction due to LRU cache capacity limits");
Console.WriteLine("2. Chunks unloaded during benchmark cleanup");
Console.WriteLine("3. All-air chunks using flyweight pattern (counted once)");
Console.WriteLine("4. Garbage collection removing unreferenced chunks");
Console.ResetColor();
}
}
} }
public class BenchmarkResult public class BenchmarkResult