diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2022-09-22 10:28:37 +0200 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2022-09-22 14:49:35 +0200 |
| commit | 6171ab09f1df2ab3475a7b28ece383a9f87a77c5 (patch) | |
| tree | 54a7ae4ef7c482dfdc04ba3eef37ab428bee3b33 /opendc-simulator/opendc-simulator-compute/src/main/kotlin | |
| parent | 507ff6223d277ebc6744b92b4030d94f20a92a02 (diff) | |
refactor(sim/compute): Extract Random dependency from interference model
This change moves the Random dependency outside the interference model,
to allow the interference model to be completely immutable and passable
between different simulations.
Diffstat (limited to 'opendc-simulator/opendc-simulator-compute/src/main/kotlin')
8 files changed, 49 insertions, 42 deletions
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) { |
