diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2020-03-11 20:02:27 +0100 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2020-03-11 20:02:27 +0100 |
| commit | 7665c089ac44166f284d5757087ea1e7b3bc0a2d (patch) | |
| tree | 7c1bbb69ea19014d3bf3848ce143cfdbd2289ca2 | |
| parent | 0655127dcd945289f045d8e04304e6a050e2a2f9 (diff) | |
| parent | d1d9e059cb83c1d8cf01e704136d0af2b6564e5b (diff) | |
Merge branch '2.x-sc20-setup' into '2.x'
Pass all relevant SC20 parameters as arguments
See merge request opendc/opendc-simulator!39
5 files changed, 79 insertions, 51 deletions
diff --git a/opendc/opendc-core/src/main/kotlin/com/atlarge/opendc/core/workload/PerformanceInterferenceModel.kt b/opendc/opendc-core/src/main/kotlin/com/atlarge/opendc/core/workload/PerformanceInterferenceModel.kt index 5e0928b7..bc9b0b06 100644 --- a/opendc/opendc-core/src/main/kotlin/com/atlarge/opendc/core/workload/PerformanceInterferenceModel.kt +++ b/opendc/opendc-core/src/main/kotlin/com/atlarge/opendc/core/workload/PerformanceInterferenceModel.kt @@ -17,7 +17,7 @@ data class PerformanceInterferenceModel( val items: Set<PerformanceInterferenceModelItem> ) { fun apply(colocatedWorkloads: Set<Resource>): Double { - val colocatedWorkloadIds = colocatedWorkloads.map { it.uid } + val colocatedWorkloadIds = colocatedWorkloads.map { it.name } val intersectingItems = items.filter { item -> colocatedWorkloadIds.intersect(item.workloadIds).size > 1 } diff --git a/opendc/opendc-experiments-sc20/build.gradle.kts b/opendc/opendc-experiments-sc20/build.gradle.kts index 348f6f77..d3b37336 100644 --- a/opendc/opendc-experiments-sc20/build.gradle.kts +++ b/opendc/opendc-experiments-sc20/build.gradle.kts @@ -31,13 +31,15 @@ plugins { } application { - mainClassName = "com.atlarge.opendc.experiments.sc20.TestExperiment" + mainClassName = "com.atlarge.opendc.experiments.sc20.TestExperimentKt" } dependencies { api(project(":opendc:opendc-core")) implementation(project(":opendc:opendc-format")) implementation(kotlin("stdlib")) + implementation("com.xenomachina:kotlin-argparser:2.0.7") + api("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8") runtimeOnly(project(":odcsim:odcsim-engine-omega")) testImplementation("org.junit.jupiter:junit-jupiter-api:${Library.JUNIT_JUPITER}") diff --git a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20HypervisorMonitor.kt b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20HypervisorMonitor.kt index 55a0ce75..90874ea3 100644 --- a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20HypervisorMonitor.kt +++ b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20HypervisorMonitor.kt @@ -8,8 +8,10 @@ import java.io.BufferedWriter import java.io.Closeable import java.io.FileWriter -class Sc20HypervisorMonitor : HypervisorMonitor, Closeable { - private val outputFile = BufferedWriter(FileWriter("sc20-experiment-results.csv")) +class Sc20HypervisorMonitor( + destination: String +) : HypervisorMonitor, Closeable { + private val outputFile = BufferedWriter(FileWriter(destination)) init { outputFile.write("time,requestedBurst,grantedBurst,numberOfDeployedImages,server,hostUsage,powerDraw\n") diff --git a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt index b48abf2e..f5c98160 100644 --- a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt +++ b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt @@ -36,6 +36,10 @@ import com.atlarge.opendc.compute.virt.service.allocation.AvailableMemoryAllocat import com.atlarge.opendc.format.environment.sc20.Sc20ClusterEnvironmentReader import com.atlarge.opendc.format.trace.sc20.Sc20PerformanceInterferenceReader import com.atlarge.opendc.format.trace.sc20.Sc20TraceReader +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import com.xenomachina.argparser.ArgParser +import com.xenomachina.argparser.default import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -43,59 +47,69 @@ import java.io.File import java.util.ServiceLoader import kotlin.math.max +class ExperimentParameters(parser: ArgParser) { + val traceDirectory by parser.storing("path to the trace directory") + val environmentFile by parser.storing("path to the environment file") + val outputFile by parser.storing("path to where the output should be stored") + .default { "sc20-experiment-results.csv" } + val selectedVms by parser.storing("the VMs to run") { + val vms: List<String> = jacksonObjectMapper().readValue(this.replace('\'', '"')) + vms + } + .default { + emptyList() + } +} + /** * Main entry point of the experiment. */ fun main(args: Array<String>) { - if (args.size < 2) { - println("error: Please provide path to directory containing VM trace files and the path to the environment file") - return - } - - val hypervisorMonitor = Sc20HypervisorMonitor() - val monitor = object : ServerMonitor { - override suspend fun onUpdate(server: Server, previousState: ServerState) { - println(server) + ArgParser(args).parseInto(::ExperimentParameters).run { + val hypervisorMonitor = Sc20HypervisorMonitor(outputFile) + val monitor = object : ServerMonitor { + override suspend fun onUpdate(server: Server, previousState: ServerState) { + println(server) + } } - } - val provider = ServiceLoader.load(SimulationEngineProvider::class.java).first() - val system = provider("test") - val root = system.newDomain("root") + val provider = ServiceLoader.load(SimulationEngineProvider::class.java).first() + val system = provider("test") + val root = system.newDomain("root") + + root.launch { + val environment = Sc20ClusterEnvironmentReader(File(environmentFile)) + .use { it.construct(root) } - root.launch { - val environment = Sc20ClusterEnvironmentReader(File(args[1])) - .use { it.construct(root) } + val performanceInterferenceModel = Sc20PerformanceInterferenceReader( + object {}.javaClass.getResourceAsStream("/env/performance-interference.json") + ).construct() - val performanceInterferenceModel = Sc20PerformanceInterferenceReader( - object {}.javaClass.getResourceAsStream("/env/performance-interference.json") - ).construct() + println(simulationContext.clock.instant()) - println(simulationContext.clock.instant()) + val scheduler = SimpleVirtProvisioningService( + AvailableMemoryAllocationPolicy(), + simulationContext, + environment.platforms[0].zones[0].services[ProvisioningService.Key], + hypervisorMonitor + ) - val scheduler = SimpleVirtProvisioningService( - AvailableMemoryAllocationPolicy(), - simulationContext, - environment.platforms[0].zones[0].services[ProvisioningService.Key], - hypervisorMonitor - ) + val reader = Sc20TraceReader(File(traceDirectory), performanceInterferenceModel, selectedVms) + while (reader.hasNext()) { + val (time, workload) = reader.next() + delay(max(0, time * 1000 - simulationContext.clock.millis())) + scheduler.deploy(workload.image, monitor, Flavor(workload.image.cores, workload.image.requiredMemory)) + } - val reader = Sc20TraceReader(File(args[0]), performanceInterferenceModel) -// delay(1376314846 * 1000L) - while (reader.hasNext()) { - val (time, workload) = reader.next() - delay(max(0, time * 1000 - simulationContext.clock.millis())) - scheduler.deploy(workload.image, monitor, Flavor(workload.image.cores, workload.image.requiredMemory)) + println(simulationContext.clock.instant()) } - println(simulationContext.clock.instant()) - } + runBlocking { + system.run() + system.terminate() + } - runBlocking { - system.run() - system.terminate() + // Explicitly close the monitor to flush its buffer + hypervisorMonitor.close() } - - // Explicitly close the monitor to flush its buffer - hypervisorMonitor.close() } diff --git a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20TraceReader.kt b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20TraceReader.kt index d4656823..498f147f 100644 --- a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20TraceReader.kt +++ b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20TraceReader.kt @@ -45,7 +45,8 @@ import java.util.UUID */ class Sc20TraceReader( traceDirectory: File, - performanceInterferenceModel: PerformanceInterferenceModel + performanceInterferenceModel: PerformanceInterferenceModel, + selectedVms: List<String> ) : TraceReader<VmWorkload> { /** * The internal iterator to use for this reader. @@ -56,7 +57,7 @@ class Sc20TraceReader( * Initialize the reader. */ init { - val entries = mutableMapOf<String, TraceEntry<VmWorkload>>() + val entries = mutableMapOf<UUID, TraceEntry<VmWorkload>>() val timestampCol = 0 val cpuUsageCol = 1 @@ -65,9 +66,18 @@ class Sc20TraceReader( val provisionedMemoryCol = 20 val traceInterval = 5 * 60 * 1000L - traceDirectory.walk() - .filterNot { it.isDirectory } - .filter { it.extension == "csv" || it.extension == "txt" } + val vms = if (selectedVms.isEmpty()) { + traceDirectory.walk() + .filterNot { it.isDirectory } + .filter { it.extension == "csv" || it.extension == "txt" } + .toList() + } else { + selectedVms.map { + File(traceDirectory, it) + } + } + + vms .forEach { vmFile -> println(vmFile) val flopsHistory = mutableListOf<FlopsHistoryFragment>() @@ -112,7 +122,7 @@ class Sc20TraceReader( } } - val uuid = UUID(0L, vmId.hashCode().toLong()) + val uuid = UUID.randomUUID() val relevantPerformanceInterferenceModelItems = PerformanceInterferenceModel( performanceInterferenceModel.items.filter { it.workloadIds.contains(uuid) }.toSet() @@ -129,7 +139,7 @@ class Sc20TraceReader( requiredMemory ) ) - entries[vmId] = TraceEntryImpl( + entries[uuid] = TraceEntryImpl( flopsHistory.firstOrNull()?.tick ?: -1, vmWorkload ) |
