diff options
Diffstat (limited to 'opendc-simulator/opendc-simulator-compute/src')
11 files changed, 78 insertions, 55 deletions
diff --git a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt index 02b48fa7..c3332d66 100644 --- a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt +++ b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt @@ -37,6 +37,7 @@ import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine import org.openjdk.jmh.annotations.* +import java.util.SplittableRandom import java.util.concurrent.ThreadLocalRandom import java.util.concurrent.TimeUnit @@ -85,7 +86,8 @@ class SimMachineBenchmarks { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(engine, null) + val random = SplittableRandom(1) + val hypervisor = SimSpaceSharedHypervisor(engine, null, random) launch { machine.runWorkload(hypervisor) } @@ -107,7 +109,8 @@ class SimMachineBenchmarks { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimFairShareHypervisor(engine, null) + val random = SplittableRandom(1) + val hypervisor = SimFairShareHypervisor(engine, null, random) launch { machine.runWorkload(hypervisor) } @@ -129,7 +132,8 @@ class SimMachineBenchmarks { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimFairShareHypervisor(engine, null) + val random = SplittableRandom(1) + val hypervisor = SimFairShareHypervisor(engine, null, random) launch { machine.runWorkload(hypervisor) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt index 98dab28f..2cabeece 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimAbstractHypervisor.kt @@ -31,6 +31,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.flow.* import org.opendc.simulator.flow.mux.FlowMultiplexer +import java.util.SplittableRandom import kotlin.math.roundToLong /** @@ -38,10 +39,12 @@ import kotlin.math.roundToLong * * @param engine The [FlowEngine] to drive the simulation. * @param scalingGovernor The scaling governor to use for scaling the CPU frequency of the underlying hardware. + * @param random A randomness generator for the interference calculations. */ public abstract class SimAbstractHypervisor( protected val engine: FlowEngine, - private val scalingGovernor: ScalingGovernor? + private val scalingGovernor: ScalingGovernor?, + private val random: SplittableRandom ) : SimHypervisor, FlowConvergenceListener { /** * The machine on which the hypervisor runs. @@ -142,8 +145,12 @@ public abstract class SimAbstractHypervisor( if (delta > 0) { _counters.record() + val mux = mux + val load = mux.rate / mux.capacity.coerceAtLeast(1.0) + val random = random + for (vm in _vms) { - vm._counters.record() + vm._counters.record(random, load) } } @@ -351,7 +358,7 @@ public abstract class SimAbstractHypervisor( /** * Record the CPU time of the hypervisor. */ - fun record() { + fun record(random: SplittableRandom, load: Double) { val cpuTime = _cpuTime val previous = _previous @@ -383,9 +390,7 @@ public abstract class SimAbstractHypervisor( // Compute the performance penalty due to flow interference val key = key if (key != null) { - val mux = mux - val load = mux.rate / mux.capacity.coerceAtLeast(1.0) - val penalty = 1 - key.apply(load) + val penalty = 1 - key.apply(random, load) val interference = (actualDelta * d * penalty).roundToLong() if (interference > 0) { diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt index 66453835..4435a422 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisor.kt @@ -29,6 +29,7 @@ import org.opendc.simulator.compute.workload.SimWorkload import org.opendc.simulator.flow.FlowEngine import org.opendc.simulator.flow.mux.FlowMultiplexer import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer +import java.util.SplittableRandom /** * A [SimHypervisor] that distributes the computing requirements of multiple [SimWorkload]s on a single [SimMachine] @@ -36,11 +37,13 @@ import org.opendc.simulator.flow.mux.MaxMinFlowMultiplexer * * @param engine The [FlowEngine] to manage the machine's resources. * @param scalingGovernor The CPU frequency scaling governor to use for the hypervisor. + * @param random A randomness generator for the interference calculations. */ public class SimFairShareHypervisor( engine: FlowEngine, - scalingGovernor: ScalingGovernor? -) : SimAbstractHypervisor(engine, scalingGovernor) { + scalingGovernor: ScalingGovernor?, + random: SplittableRandom +) : SimAbstractHypervisor(engine, scalingGovernor, random) { /** * The multiplexer that distributes the computing capacity. */ diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt index ad8177d3..c7008652 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorProvider.kt @@ -24,6 +24,7 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.flow.FlowEngine +import java.util.* /** * A [SimHypervisorProvider] for the [SimFairShareHypervisor] implementation. @@ -33,6 +34,7 @@ public class SimFairShareHypervisorProvider : SimHypervisorProvider { override fun create( engine: FlowEngine, + random: SplittableRandom, scalingGovernor: ScalingGovernor?, - ): SimHypervisor = SimFairShareHypervisor(engine, scalingGovernor) + ): SimHypervisor = SimFairShareHypervisor(engine, scalingGovernor, random) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt index 6ee523fd..020a2a60 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimHypervisorProvider.kt @@ -24,6 +24,7 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.flow.FlowEngine +import java.util.SplittableRandom /** * A service provider interface for constructing a [SimHypervisor]. @@ -40,5 +41,5 @@ public interface SimHypervisorProvider { /** * Create a new [SimHypervisor] instance. */ - public fun create(engine: FlowEngine, scalingGovernor: ScalingGovernor? = null): SimHypervisor + public fun create(engine: FlowEngine, random: SplittableRandom, scalingGovernor: ScalingGovernor? = null): SimHypervisor } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt index 7976077c..51bf4ce5 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisor.kt @@ -27,14 +27,20 @@ import org.opendc.simulator.compute.model.MachineModel import org.opendc.simulator.flow.FlowEngine import org.opendc.simulator.flow.mux.FlowMultiplexer import org.opendc.simulator.flow.mux.ForwardingFlowMultiplexer +import java.util.SplittableRandom /** * A [SimHypervisor] that allocates its sub-resources exclusively for the virtual machine that it hosts. + * + * @param engine The [FlowEngine] to manage the machine's resources. + * @param scalingGovernor The CPU frequency scaling governor to use for the hypervisor. + * @param random A randomness generator for the interference calculations. */ public class SimSpaceSharedHypervisor( engine: FlowEngine, scalingGovernor: ScalingGovernor?, -) : SimAbstractHypervisor(engine, scalingGovernor) { + random: SplittableRandom +) : SimAbstractHypervisor(engine, scalingGovernor, random) { override val mux: FlowMultiplexer = ForwardingFlowMultiplexer(engine, this) override fun canFit(model: MachineModel): Boolean { diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt index f7456797..05c54528 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorProvider.kt @@ -24,6 +24,7 @@ package org.opendc.simulator.compute.kernel import org.opendc.simulator.compute.kernel.cpufreq.ScalingGovernor import org.opendc.simulator.flow.FlowEngine +import java.util.* /** * A [SimHypervisorProvider] for the [SimSpaceSharedHypervisor] implementation. @@ -33,6 +34,7 @@ public class SimSpaceSharedHypervisorProvider : SimHypervisorProvider { override fun create( engine: FlowEngine, + random: SplittableRandom, scalingGovernor: ScalingGovernor?, - ): SimHypervisor = SimSpaceSharedHypervisor(engine, scalingGovernor) + ): SimHypervisor = SimSpaceSharedHypervisor(engine, scalingGovernor, random) } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceMember.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceMember.kt index 2f3dd74b..04203c63 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceMember.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceMember.kt @@ -22,6 +22,8 @@ package org.opendc.simulator.compute.kernel.interference +import java.util.* + /** * A participant of an interference domain. */ @@ -39,9 +41,10 @@ public interface VmInterferenceMember { /** * Compute the performance score of the member in this interference domain. * + * @param random The source of randomness to apply when computing the performance score. * @param load The overall load on the interference domain. * @return A score representing the performance score to be applied to the member, with 1 * meaning no influence, <1 means that performance degrades, and >1 means that performance improves. */ - public fun apply(load: Double): Double + public fun apply(random: SplittableRandom, load: Double): Double } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceModel.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceModel.kt index b9eee536..3ea869d4 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceModel.kt +++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/kernel/interference/VmInterferenceModel.kt @@ -32,7 +32,6 @@ import java.util.* * @param members The members belonging to each group. * @param membership The identifier of each key. * @param size The number of groups. - * @param seed The seed to use for randomly selecting the virtual machines that are affected. */ public class VmInterferenceModel private constructor( private val idMapping: Map<String, Int>, @@ -40,25 +39,12 @@ public class VmInterferenceModel private constructor( private val membership: Array<IntArray>, private val targets: DoubleArray, private val scores: DoubleArray, - private val size: Int, - seed: Long, + private val size: Int ) { /** - * A [SplittableRandom] used for selecting the virtual machines that are affected. - */ - private val random = SplittableRandom(seed) - - /** * Construct a new [VmInterferenceDomain]. */ - public fun newDomain(): VmInterferenceDomain = InterferenceDomainImpl(idMapping, members, membership, targets, scores, random) - - /** - * Create a copy of this model with a different seed. - */ - public fun withSeed(seed: Long): VmInterferenceModel { - return VmInterferenceModel(idMapping, members, membership, targets, scores, size, seed) - } + public fun newDomain(): VmInterferenceDomain = InterferenceDomainImpl(idMapping, members, membership, targets, scores) public companion object { /** @@ -73,11 +59,6 @@ public class VmInterferenceModel private constructor( */ public class Builder internal constructor() { /** - * The initial capacity of the builder. - */ - private val INITIAL_CAPACITY = 256 - - /** * The target load of each group. */ private var _targets = DoubleArray(INITIAL_CAPACITY) { Double.POSITIVE_INFINITY } @@ -125,7 +106,7 @@ public class VmInterferenceModel private constructor( /** * Build the [VmInterferenceModel]. */ - public fun build(seed: Long = 0): VmInterferenceModel { + public fun build(): VmInterferenceModel { val size = size val targets = _targets val scores = _scores @@ -176,8 +157,7 @@ public class VmInterferenceModel private constructor( membership.map { it.value.toIntArray() }.toTypedArray(), newTargets, newScores, - size, - seed + size ) } @@ -191,6 +171,13 @@ public class VmInterferenceModel private constructor( _targets = _targets.copyOf(newSize) _scores = _scores.copyOf(newSize) } + + private companion object { + /** + * The initial capacity of the builder. + */ + const val INITIAL_CAPACITY = 256 + } } /** @@ -202,7 +189,6 @@ public class VmInterferenceModel private constructor( private val membership: Array<IntArray>, private val targets: DoubleArray, private val scores: DoubleArray, - private val random: SplittableRandom ) : VmInterferenceDomain { /** * Keys registered with this domain. @@ -221,7 +207,7 @@ public class VmInterferenceModel private constructor( override fun getMember(id: String): VmInterferenceMember? { val intId = idMapping[id] ?: return null - return keys.computeIfAbsent(intId) { InterferenceMemberImpl(it, this, membership[it], members, targets, scores, random) } + return keys.computeIfAbsent(intId) { InterferenceMemberImpl(it, this, membership[it], members, targets, scores) } } override fun toString(): String = "VmInterferenceDomain" @@ -307,8 +293,7 @@ public class VmInterferenceModel private constructor( @JvmField val membership: IntArray, private val members: Array<IntArray>, private val targets: DoubleArray, - private val scores: DoubleArray, - private val random: SplittableRandom + private val scores: DoubleArray ) : VmInterferenceMember, Comparable<InterferenceMemberImpl> { /** * The active groups to which the key belongs. @@ -333,7 +318,7 @@ public class VmInterferenceModel private constructor( } } - override fun apply(load: Double): Double { + override fun apply(random: SplittableRandom, load: Double): Double { val groupsSize = groupsSize if (groupsSize == 0) { diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt index 15d32002..23d832e8 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimFairShareHypervisorTest.kt @@ -43,6 +43,7 @@ import org.opendc.simulator.compute.workload.SimTraceFragment import org.opendc.simulator.compute.workload.SimTraceWorkload import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine +import java.util.* /** * Test suite for the [SimHypervisor] class. @@ -77,7 +78,8 @@ internal class SimFairShareHypervisorTest { val platform = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine(platform, model, SimplePowerDriver(ConstantPowerModel(0.0))) - val hypervisor = SimFairShareHypervisor(platform, PerformanceScalingGovernor()) + val random = SplittableRandom(1) + val hypervisor = SimFairShareHypervisor(platform, PerformanceScalingGovernor(), random) launch { machine.runWorkload(hypervisor) @@ -128,7 +130,8 @@ internal class SimFairShareHypervisorTest { val machine = SimBareMetalMachine( platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimFairShareHypervisor(platform, null) + val random = SplittableRandom(1) + val hypervisor = SimFairShareHypervisor(platform, null, random) launch { machine.runWorkload(hypervisor) @@ -167,7 +170,8 @@ internal class SimFairShareHypervisorTest { val platform = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine(platform, model, SimplePowerDriver(ConstantPowerModel(0.0))) - val hypervisor = SimFairShareHypervisor(platform, null) + val random = SplittableRandom(1) + val hypervisor = SimFairShareHypervisor(platform, null, random) assertDoesNotThrow { launch { @@ -197,7 +201,8 @@ internal class SimFairShareHypervisorTest { val machine = SimBareMetalMachine( platform, model, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimFairShareHypervisor(platform, null) + val random = SplittableRandom(1) + val hypervisor = SimFairShareHypervisor(platform, null, random) val duration = 5 * 60L val workloadA = diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt index 0f533130..9471f548 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/kernel/SimSpaceSharedHypervisorTest.kt @@ -40,6 +40,7 @@ import org.opendc.simulator.compute.runWorkload import org.opendc.simulator.compute.workload.* import org.opendc.simulator.core.runBlockingSimulation import org.opendc.simulator.flow.FlowEngine +import java.util.* /** * A test suite for the [SimSpaceSharedHypervisor]. @@ -75,7 +76,8 @@ internal class SimSpaceSharedHypervisorTest { val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine(engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0))) - val hypervisor = SimSpaceSharedHypervisor(engine, null) + val random = SplittableRandom(1) + val hypervisor = SimSpaceSharedHypervisor(engine, null, random) launch { machine.runWorkload(hypervisor) } val vm = hypervisor.newMachine(machineModel) @@ -97,7 +99,8 @@ internal class SimSpaceSharedHypervisorTest { val workload = SimRuntimeWorkload(duration) val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine(engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0))) - val hypervisor = SimSpaceSharedHypervisor(engine, null) + val random = SplittableRandom(1) + val hypervisor = SimSpaceSharedHypervisor(engine, null, random) launch { machine.runWorkload(hypervisor) } yield() @@ -121,7 +124,8 @@ internal class SimSpaceSharedHypervisorTest { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(engine, null) + val random = SplittableRandom(1) + val hypervisor = SimSpaceSharedHypervisor(engine, null, random) launch { machine.runWorkload(hypervisor) } yield() @@ -142,7 +146,8 @@ internal class SimSpaceSharedHypervisorTest { val machine = SimBareMetalMachine( engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(engine, null) + val random = SplittableRandom(1) + val hypervisor = SimSpaceSharedHypervisor(engine, null, random) launch { machine.runWorkload(hypervisor) } yield() @@ -169,7 +174,8 @@ internal class SimSpaceSharedHypervisorTest { fun testConcurrentWorkloadFails() = runBlockingSimulation { val engine = FlowEngine(coroutineContext, clock) val machine = SimBareMetalMachine(engine, machineModel, SimplePowerDriver(ConstantPowerModel(0.0))) - val hypervisor = SimSpaceSharedHypervisor(engine, null) + val random = SplittableRandom(1) + val hypervisor = SimSpaceSharedHypervisor(engine, null, random) launch { machine.runWorkload(hypervisor) } yield() @@ -193,7 +199,8 @@ internal class SimSpaceSharedHypervisorTest { val machine = SimBareMetalMachine( interpreter, machineModel, SimplePowerDriver(ConstantPowerModel(0.0)) ) - val hypervisor = SimSpaceSharedHypervisor(interpreter, null) + val random = SplittableRandom(1) + val hypervisor = SimSpaceSharedHypervisor(interpreter, null, random) launch { machine.runWorkload(hypervisor) } yield() |
