diff options
| author | Dante Niewenhuis <d.niewenhuis@hotmail.com> | 2024-09-16 11:29:26 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-16 11:29:26 +0200 |
| commit | 4a010c6b9e033314a2624a0756dcdc7f17010d9d (patch) | |
| tree | 70dc26e98cf8421eb5db7f62cf63d4ea2399c505 /opendc-compute/opendc-compute-simulator | |
| parent | 5047e4a25a0814f96852882f02c4017e1d5f81e7 (diff) | |
All simulation are now run with a single CPU and single MemoryUnit. multi CPUs are combined into one. This is for performance and explainability. (#255)
Diffstat (limited to 'opendc-compute/opendc-compute-simulator')
4 files changed, 46 insertions, 55 deletions
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index ac0a8043..e681403c 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -41,8 +41,6 @@ import org.opendc.simulator.compute.SimMachineContext import org.opendc.simulator.compute.kernel.SimHypervisor import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.model.ProcessingNode -import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.compute.workload.SimWorkloads import java.time.Duration @@ -96,10 +94,9 @@ public class SimHost( private val model: HostModel = HostModel( - machine.model.cpus.sumOf { it.frequency }, - machine.model.cpus.size, - machine.model.cpus.sumOf { it.node.coreCount }, - machine.model.memory.sumOf { it.size }, + machine.model.cpu.totalCapacity, + machine.model.cpu.coreCount, + machine.model.memory.size, ) /** @@ -349,22 +346,14 @@ public class SimHost( * Convert flavor to machine model. */ private fun Flavor.toMachineModel(): MachineModel { - val originalCpu = machine.model.cpus[0] - val originalNode = originalCpu.node - val cpuCapacity = (this.meta["cpu-capacity"] as? Double ?: Double.MAX_VALUE).coerceAtMost(originalCpu.frequency) - val processingNode = ProcessingNode(originalNode.vendor, originalNode.modelName, originalNode.architecture, coreCount) - val processingUnits = (0 until coreCount).map { ProcessingUnit(processingNode, it, cpuCapacity) } - val memoryUnits = listOf(MemoryUnit("Generic", "Generic", 3200.0, memorySize)) - - val model = MachineModel(processingUnits, memoryUnits) - return if (optimize) model.optimize() else model + return MachineModel(machine.model.cpu, MemoryUnit("Generic", "Generic", 3200.0, memorySize)) } private var localLastReport = clock.millis() private var localUptime = 0L private var localDowntime = 0L private var localBootTime: Instant? = null - private val localCpuLimit = machine.model.cpus.sumOf { it.frequency * it.node.coreCount } + private val localCpuLimit = machine.model.cpu.totalCapacity /** * Helper function to track the uptime of a machine. diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt index ea8f51d0..412da37f 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/DefaultWorkloadMapper.kt @@ -39,8 +39,8 @@ internal object DefaultWorkloadMapper : SimWorkloadMapper { override fun createWorkload(task: Task): SimWorkload { val workload = delegate.createWorkload(task) - // FIXME: look at connecting this to frontend. Probably not needed since the duration is so small - val bootWorkload = SimWorkloads.runtime(Duration.ofMillis(1), 0.8, 0L, 0L) + // FIXME: look at connecting this to frontend. This does currently not work correctly + val bootWorkload = SimWorkloads.runtime(Duration.ofMillis(0), 1.0, 0L, 0L) return SimWorkloads.chain(bootWorkload, workload) } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt index 1925233f..cf6c146a 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/internal/Guest.kt @@ -31,7 +31,6 @@ import org.opendc.compute.simulator.SimHost import org.opendc.compute.simulator.SimWorkloadMapper import org.opendc.simulator.compute.SimMachineContext import org.opendc.simulator.compute.kernel.SimHypervisor -import org.opendc.simulator.compute.kernel.SimVirtualMachine import org.opendc.simulator.compute.workload.SimWorkload import java.time.Duration import java.time.Instant @@ -47,7 +46,7 @@ internal class Guest( private val mapper: SimWorkloadMapper, private val listener: GuestListener, val task: Task, - val machine: SimVirtualMachine, + val machine: SimHypervisor.SimVirtualMachine, ) { /** * The state of the [Guest]. @@ -225,7 +224,7 @@ internal class Guest( private var localDowntime = 0L private var localLastReport = clock.millis() private var localBootTime: Instant? = null - private val localCpuLimit = machine.model.cpus.sumOf { it.frequency } + private val localCpuLimit = machine.model.cpu.totalCapacity /** * Helper function to track the uptime and downtime of the guest. diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 77cd2291..b5bc66a9 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -38,10 +38,9 @@ import org.opendc.compute.service.driver.Host import org.opendc.compute.service.driver.HostListener import org.opendc.simulator.compute.SimBareMetalMachine import org.opendc.simulator.compute.kernel.SimHypervisor +import org.opendc.simulator.compute.model.Cpu import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.compute.model.MemoryUnit -import org.opendc.simulator.compute.model.ProcessingNode -import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.workload.SimTrace import org.opendc.simulator.compute.workload.SimTraceFragment import org.opendc.simulator.flow2.FlowEngine @@ -60,14 +59,18 @@ internal class SimHostTest { @BeforeEach fun setUp() { - val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2) - machineModel = MachineModel( - // cpus - List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) }, + Cpu( + 0, + 2, + 3200.0, + "Intel", + "Xeon", + "amd64", + ), // memory - List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) }, + MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000 * 4), ) } @@ -102,11 +105,11 @@ internal class SimHostTest { mapOf( "workload" to SimTrace.ofFragments( - SimTraceFragment(0, duration * 1000, 2 * 28.0, 2), - SimTraceFragment(duration * 1000, duration * 1000, 2 * 3500.0, 2), + SimTraceFragment(0, duration * 1000, 0.0, 2), + SimTraceFragment(duration * 1000, duration * 1000, 3200.0, 2), SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2), - SimTraceFragment(duration * 3000, duration * 1000, 2 * 183.0, 2), - ).createWorkload(1), + SimTraceFragment(duration * 3000, duration * 1000, 6500.0, 2), + ).createWorkload(0), ), ) @@ -134,16 +137,16 @@ internal class SimHostTest { } // Ensure last cycle is collected - delay(1000L * duration) +// delay(1000L * duration) host.close() val cpuStats = host.getCpuStats() assertAll( - { assertEquals(347908, cpuStats.activeTime, "Active time does not match") }, - { assertEquals(2652092, cpuStats.idleTime, "Idle time does not match") }, - { assertEquals(1, cpuStats.stealTime, "Steal time does not match") }, - { assertEquals(1500000, timeSource.millis()) }, + { assertEquals(450000, cpuStats.activeTime, "Active time does not match") }, + { assertEquals(750000, cpuStats.idleTime, "Idle time does not match") }, + { assertEquals(4688, cpuStats.stealTime, "Steal time does not match") }, + { assertEquals(1200000, timeSource.millis()) }, ) } @@ -178,11 +181,11 @@ internal class SimHostTest { mapOf( "workload" to SimTrace.ofFragments( - SimTraceFragment(0, duration * 1000, 2 * 28.0, 2), - SimTraceFragment(duration * 1000, duration * 1000, 2 * 3500.0, 2), + SimTraceFragment(0, duration * 1000, 0.0, 2), + SimTraceFragment(duration * 1000, duration * 1000, 3200.0, 2), SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2), - SimTraceFragment(duration * 3000, duration * 1000, 2 * 183.0, 2), - ).createWorkload(1), + SimTraceFragment(duration * 3000, duration * 1000, 6500.0, 2), + ).createWorkload(0), ), ) val vmImageB = @@ -193,11 +196,11 @@ internal class SimHostTest { mapOf( "workload" to SimTrace.ofFragments( - SimTraceFragment(0, duration * 1000, 2 * 28.0, 2), - SimTraceFragment(duration * 1000, duration * 1000, 2 * 3100.0, 2), + SimTraceFragment(0, duration * 1000, 0.0, 2), + SimTraceFragment(duration * 1000, duration * 1000, 3200.0, 2), SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2), - SimTraceFragment(duration * 3000, duration * 1000, 2 * 73.0, 2), - ).createWorkload(1), + SimTraceFragment(duration * 3000, duration * 1000, 6500.0, 2), + ).createWorkload(0), ), ) @@ -237,9 +240,9 @@ internal class SimHostTest { val cpuStats = host.getCpuStats() assertAll( - { assertEquals(629252, cpuStats.activeTime, "Active time does not match") }, - { assertEquals(2370748, cpuStats.idleTime, "Idle time does not match") }, - { assertEquals(18754, cpuStats.stealTime, "Steal time does not match") }, + { assertEquals(600000, cpuStats.activeTime, "Active time does not match") }, + { assertEquals(900000, cpuStats.idleTime, "Idle time does not match") }, + { assertEquals(309375, cpuStats.stealTime, "Steal time does not match") }, { assertEquals(1500000, timeSource.millis()) }, ) } @@ -274,11 +277,11 @@ internal class SimHostTest { mapOf( "workload" to SimTrace.ofFragments( - SimTraceFragment(0, duration * 1000, 2 * 28.0, 2), - SimTraceFragment(duration * 1000L, duration * 1000, 2 * 3500.0, 2), - SimTraceFragment(duration * 2000L, duration * 1000, 0.0, 2), - SimTraceFragment(duration * 3000L, duration * 1000, 2 * 183.0, 2), - ).createWorkload(1), + SimTraceFragment(0, duration * 1000, 0.0, 2), + SimTraceFragment(duration * 1000, duration * 1000, 3200.0, 2), + SimTraceFragment(duration * 2000, duration * 1000, 0.0, 2), + SimTraceFragment(duration * 3000, duration * 1000, 6500.0, 2), + ).createWorkload(0), ), ) val flavor = MockFlavor(2, 0) @@ -318,8 +321,8 @@ internal class SimHostTest { val guestSysStats = host.getSystemStats(server) assertAll( - { assertEquals(2062046, cpuStats.idleTime, "Idle time does not match") }, - { assertEquals(347954, cpuStats.activeTime, "Active time does not match") }, + { assertEquals(755000, cpuStats.idleTime, "Idle time does not match") }, + { assertEquals(450000, cpuStats.activeTime, "Active time does not match") }, { assertEquals(1205000, sysStats.uptime.toMillis(), "Uptime does not match") }, { assertEquals(300000, sysStats.downtime.toMillis(), "Downtime does not match") }, { assertEquals(1205000, guestSysStats.uptime.toMillis(), "Guest uptime does not match") }, |
