136 lines
5.6 KiB
C#
136 lines
5.6 KiB
C#
using NUnit.Framework;
|
|
using VMdemo.Core;
|
|
using VMdemo.Simulation;
|
|
|
|
namespace VMdemo.Tests.EditMode
|
|
{
|
|
public class Step6StatsCollectorTests
|
|
{
|
|
[Test]
|
|
public void StatsCollector_Reset_ClearsAllCountersAndRates()
|
|
{
|
|
var stats = new StatsCollector();
|
|
stats.RecordAccess(tlbHit: true, pageTableHit: false, pageFault: false, cost: 1);
|
|
stats.RecordAccess(tlbHit: false, pageTableHit: false, pageFault: true, cost: 104);
|
|
|
|
stats.Reset();
|
|
|
|
Assert.That(stats.TotalAccess, Is.EqualTo(0));
|
|
Assert.That(stats.TlbHit, Is.EqualTo(0));
|
|
Assert.That(stats.PageTableHit, Is.EqualTo(0));
|
|
Assert.That(stats.PageFault, Is.EqualTo(0));
|
|
Assert.That(stats.TotalCost, Is.EqualTo(0L));
|
|
Assert.That(stats.TlbHitRate, Is.EqualTo(0.0));
|
|
Assert.That(stats.PageTableHitRate, Is.EqualTo(0.0));
|
|
Assert.That(stats.AvgCost, Is.EqualTo(0.0));
|
|
}
|
|
|
|
[Test]
|
|
public void StatsCollector_CalculateCost_FollowsMvpCostModel()
|
|
{
|
|
var stats = new StatsCollector();
|
|
|
|
Assert.That(stats.CalculateCost(tlbHit: true, pageTableHit: false, pageFault: false, pageFaultPenalty: 100), Is.EqualTo(1));
|
|
Assert.That(stats.CalculateCost(tlbHit: false, pageTableHit: true, pageFault: false, pageFaultPenalty: 100), Is.EqualTo(4));
|
|
Assert.That(stats.CalculateCost(tlbHit: false, pageTableHit: false, pageFault: true, pageFaultPenalty: 100), Is.EqualTo(104));
|
|
}
|
|
|
|
[Test]
|
|
public void StatsCollector_RecordAccess_AggregatesCountersRatesAndAverage()
|
|
{
|
|
var stats = new StatsCollector();
|
|
|
|
stats.RecordAccess(tlbHit: true, pageTableHit: false, pageFault: false, cost: 1);
|
|
stats.RecordAccess(tlbHit: false, pageTableHit: true, pageFault: false, cost: 4);
|
|
stats.RecordAccess(tlbHit: false, pageTableHit: false, pageFault: true, cost: 104);
|
|
|
|
Assert.That(stats.TotalAccess, Is.EqualTo(3));
|
|
Assert.That(stats.TlbHit, Is.EqualTo(1));
|
|
Assert.That(stats.PageTableHit, Is.EqualTo(1));
|
|
Assert.That(stats.PageFault, Is.EqualTo(1));
|
|
Assert.That(stats.TotalCost, Is.EqualTo(109L));
|
|
Assert.That(stats.TlbHitRate, Is.EqualTo(1.0 / 3.0).Within(1e-12));
|
|
Assert.That(stats.PageTableHitRate, Is.EqualTo(1.0 / 3.0).Within(1e-12));
|
|
Assert.That(stats.AvgCost, Is.EqualTo(109.0 / 3.0).Within(1e-12));
|
|
}
|
|
|
|
[Test]
|
|
public void TranslatorEngine_StepOnce_ToFinalize_UpdatesStatsAndCurrentCost()
|
|
{
|
|
var engine = CreateEngine(pageFaultPenalty: 120, seed: 31);
|
|
engine.SetNextVirtualAddress(0x0000_1234UL);
|
|
|
|
while (!engine.StepOnce())
|
|
{
|
|
}
|
|
|
|
Assert.That(engine.State.CurrentRound, Is.EqualTo(1));
|
|
Assert.That(engine.State.IsPageFault, Is.True);
|
|
Assert.That(engine.State.CurrentCost, Is.EqualTo(124));
|
|
Assert.That(engine.Stats.TotalAccess, Is.EqualTo(1));
|
|
Assert.That(engine.Stats.PageFault, Is.EqualTo(1));
|
|
Assert.That(engine.Stats.TotalCost, Is.EqualTo(124L));
|
|
Assert.That(engine.Stats.AvgCost, Is.EqualTo(124.0));
|
|
}
|
|
|
|
[Test]
|
|
public void TranslatorEngine_RunOneAccess_TracksBatchSummaryWithMixedPaths()
|
|
{
|
|
var engine = CreateEngine(pageFaultPenalty: 100, seed: 41);
|
|
const ulong va = 0x0000_5678UL;
|
|
|
|
var first = engine.RunOneAccess(va); // page fault
|
|
var second = engine.RunOneAccess(va); // tlb hit
|
|
|
|
engine.TlbCache.Clear();
|
|
var third = engine.RunOneAccess(va); // page table hit
|
|
|
|
Assert.IsTrue(first.PageFault);
|
|
Assert.IsTrue(second.TlbHit);
|
|
Assert.IsTrue(third.PageTableHit);
|
|
|
|
Assert.That(engine.Stats.TotalAccess, Is.EqualTo(3));
|
|
Assert.That(engine.Stats.TlbHit, Is.EqualTo(1));
|
|
Assert.That(engine.Stats.PageTableHit, Is.EqualTo(1));
|
|
Assert.That(engine.Stats.PageFault, Is.EqualTo(1));
|
|
Assert.That(engine.Stats.TotalCost, Is.EqualTo(109L));
|
|
Assert.That(engine.Stats.TlbHitRate, Is.EqualTo(1.0 / 3.0).Within(1e-12));
|
|
Assert.That(engine.Stats.PageTableHitRate, Is.EqualTo(1.0 / 3.0).Within(1e-12));
|
|
Assert.That(engine.Stats.AvgCost, Is.EqualTo(109.0 / 3.0).Within(1e-12));
|
|
}
|
|
|
|
[Test]
|
|
public void TranslatorEngine_Reset_ClearsStats()
|
|
{
|
|
var engine = CreateEngine(pageFaultPenalty: 100, seed: 51);
|
|
engine.RunOneAccess(0x0000_9ABCUL);
|
|
Assert.That(engine.Stats.TotalAccess, Is.EqualTo(1));
|
|
|
|
engine.Reset();
|
|
|
|
Assert.That(engine.Stats.TotalAccess, Is.EqualTo(0));
|
|
Assert.That(engine.Stats.TlbHit, Is.EqualTo(0));
|
|
Assert.That(engine.Stats.PageTableHit, Is.EqualTo(0));
|
|
Assert.That(engine.Stats.PageFault, Is.EqualTo(0));
|
|
Assert.That(engine.Stats.TotalCost, Is.EqualTo(0L));
|
|
Assert.That(engine.Stats.AvgCost, Is.EqualTo(0.0));
|
|
Assert.That(engine.State.CurrentCost, Is.EqualTo(0));
|
|
}
|
|
|
|
private static TranslatorEngine CreateEngine(int pageFaultPenalty, int seed)
|
|
{
|
|
var config = new SimulationConfig
|
|
{
|
|
vaBits = 32,
|
|
pageSizeKB = 4,
|
|
physicalMemoryMB = 1,
|
|
tlbEntries = 4,
|
|
accessCount = 20,
|
|
pageFaultPenalty = pageFaultPenalty
|
|
};
|
|
|
|
return new TranslatorEngine(config, seed);
|
|
}
|
|
}
|
|
}
|