summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2020-04-15 12:16:42 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2020-04-15 12:16:42 +0200
commita77829c7a8cf300a99a695423d85f905e0209286 (patch)
treef31200cdc3f108ea9b6d622df44a972ed5eed46d
parentae23970faa77c89408a4e98cb9259fb53e222bd3 (diff)
perf: Optimize performance interference
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/workload/PerformanceInterferenceModel.kt129
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt1
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt50
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/SimpleVirtProvisioningService.kt12
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/VirtProvisioningService.kt5
-rw-r--r--opendc/opendc-core/src/main/kotlin/com/atlarge/opendc/core/workload/PerformanceInterferenceModel.kt83
-rw-r--r--opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt16
-rw-r--r--opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/TestExperiment.kt18
-rw-r--r--opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/PerformanceInterferenceModelReader.kt2
-rw-r--r--opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20PerformanceInterferenceReader.kt7
-rw-r--r--opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20TraceReader.kt11
-rw-r--r--opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/vm/VmTraceReader.kt11
12 files changed, 209 insertions, 136 deletions
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/workload/PerformanceInterferenceModel.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/workload/PerformanceInterferenceModel.kt
new file mode 100644
index 00000000..ddf9bb33
--- /dev/null
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/workload/PerformanceInterferenceModel.kt
@@ -0,0 +1,129 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package com.atlarge.opendc.compute.core.workload
+
+import com.atlarge.opendc.compute.core.Server
+import java.util.SortedSet
+import java.util.TreeSet
+import kotlin.random.Random
+
+/**
+ * Meta-data key for the [PerformanceInterferenceModel] of an image.
+ */
+const val IMAGE_PERF_INTERFERENCE_MODEL = "image:performance-interference"
+
+/**
+ * Performance Interference Model describing the variability incurred by different sets of workloads if colocated.
+ *
+ * @param items The [PerformanceInterferenceModelItem]s that make up this model.
+ */
+class PerformanceInterferenceModel(
+ items: Set<PerformanceInterferenceModelItem>,
+ val random: Random = Random(0)
+) {
+ private var intersectingItems: List<PerformanceInterferenceModelItem> = emptyList()
+ private val comparator = Comparator<PerformanceInterferenceModelItem> { lhs, rhs ->
+ var cmp = lhs.performanceScore.compareTo(rhs.performanceScore)
+ if (cmp != 0) {
+ return@Comparator cmp
+ }
+
+ cmp = lhs.minServerLoad.compareTo(rhs.minServerLoad)
+ if (cmp != 0) {
+ return@Comparator cmp
+ }
+
+ lhs.hashCode().compareTo(rhs.hashCode())
+ }
+ val items = TreeSet(comparator)
+ private val colocatedWorkloads = TreeSet<String>()
+
+ init {
+ this.items.addAll(items)
+ }
+
+ fun vmStarted(server: Server) {
+ colocatedWorkloads.add(server.image.name)
+ intersectingItems = items.filter { item -> doesMatch(item) }
+ }
+
+ fun vmStopped(server: Server) {
+ colocatedWorkloads.remove(server.image.name)
+ intersectingItems = items.filter { item -> doesMatch(item) }
+ }
+
+ private fun doesMatch(item: PerformanceInterferenceModelItem): Boolean {
+ var count = 0
+ for (name in item.workloadNames.subSet(colocatedWorkloads.first(), colocatedWorkloads.last() + "\u0000")) {
+ if (name in colocatedWorkloads)
+ count++
+ if (count > 1)
+ return true
+ }
+ return false
+ }
+
+ fun apply(currentServerLoad: Double): Double {
+ if (intersectingItems.isEmpty()) {
+ return 1.0
+ }
+ val score = intersectingItems
+ .firstOrNull { it.minServerLoad <= currentServerLoad }
+
+ // Apply performance penalty to (on average) only one of the VMs
+ return if (score != null && random.nextInt(score.workloadNames.size) == 0) {
+ score.performanceScore
+ } else {
+ 1.0
+ }
+ }
+}
+
+/**
+ * Model describing how a specific set of workloads causes performance variability for each workload.
+ *
+ * @param workloadNames The names of the workloads that together cause performance variability for each workload in the set.
+ * @param minServerLoad The minimum total server load at which this interference is activated and noticeable.
+ * @param performanceScore The performance score that should be applied to each workload's performance. 1 means no
+ * influence, <1 means that performance degrades, and >1 means that performance improves.
+ */
+data class PerformanceInterferenceModelItem(
+ val workloadNames: SortedSet<String>,
+ val minServerLoad: Double,
+ val performanceScore: Double
+) {
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as PerformanceInterferenceModelItem
+
+ if (workloadNames != other.workloadNames) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int = workloadNames.hashCode()
+}
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt
index 7c088bc8..e7344fa6 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/HypervisorEvent.kt
@@ -26,6 +26,7 @@ package com.atlarge.opendc.compute.virt
import com.atlarge.opendc.compute.core.Server
import com.atlarge.opendc.compute.virt.driver.VirtDriver
+import com.atlarge.opendc.compute.virt.service.VirtProvisioningService
/**
* An event that is emitted by a [VirtDriver].
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt
index 73f9dd5c..f32f407c 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/SimpleVirtDriver.kt
@@ -40,8 +40,8 @@ import com.atlarge.opendc.compute.core.image.Image
import com.atlarge.opendc.compute.virt.HypervisorEvent
import com.atlarge.opendc.core.services.ServiceKey
import com.atlarge.opendc.core.services.ServiceRegistry
-import com.atlarge.opendc.core.workload.IMAGE_PERF_INTERFERENCE_MODEL
-import com.atlarge.opendc.core.workload.PerformanceInterferenceModel
+import com.atlarge.opendc.compute.core.workload.IMAGE_PERF_INTERFERENCE_MODEL
+import com.atlarge.opendc.compute.core.workload.PerformanceInterferenceModel
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
@@ -53,9 +53,6 @@ import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.selects.SelectClause0
import kotlinx.coroutines.selects.select
@@ -65,6 +62,7 @@ import java.util.Objects
import java.util.TreeSet
import java.util.UUID
import kotlin.coroutines.resume
+import kotlin.coroutines.suspendCoroutine
import kotlin.math.ceil
import kotlin.math.max
import kotlin.math.min
@@ -101,15 +99,6 @@ class SimpleVirtDriver(
override val events: Flow<HypervisorEvent> = eventFlow
init {
- events.filter { it is HypervisorEvent.VmsUpdated }.onEach {
- val imagesRunning = vms.map { it.server.image }.toSet()
- vms.forEach {
- val performanceModel =
- it.server.image.tags[IMAGE_PERF_INTERFERENCE_MODEL] as? PerformanceInterferenceModel?
- performanceModel?.computeIntersectingItems(imagesRunning)
- }
- }.launchIn(this)
-
launch {
try {
scheduler()
@@ -140,6 +129,7 @@ class SimpleVirtDriver(
)
availableMemory -= requiredMemory
vms.add(VmServerContext(server, events, simulationContext.domain))
+ vmStarted(server)
eventFlow.emit(HypervisorEvent.VmsUpdated(this, vms.size, availableMemory))
return server
}
@@ -148,6 +138,22 @@ class SimpleVirtDriver(
eventFlow.close()
}
+ private fun vmStarted(server: Server) {
+ vms.forEach {
+ val performanceModel =
+ it.server.image.tags[IMAGE_PERF_INTERFERENCE_MODEL] as? PerformanceInterferenceModel?
+ performanceModel?.vmStarted(server)
+ }
+ }
+
+ private fun vmStopped(server: Server) {
+ vms.forEach {
+ val performanceModel =
+ it.server.image.tags[IMAGE_PERF_INTERFERENCE_MODEL] as? PerformanceInterferenceModel?
+ performanceModel?.vmStopped(server)
+ }
+ }
+
/**
* A scheduling command processed by the scheduler.
*/
@@ -325,7 +331,7 @@ class SimpleVirtDriver(
requests.removeAll(vmRequests)
// Return vCPU `run` call: the requested burst was completed or deadline was exceeded
- vm.cont?.resume(Unit)
+ vm.chan.send(Unit)
}
}
@@ -395,7 +401,7 @@ class SimpleVirtDriver(
private var finalized: Boolean = false
lateinit var burst: LongArray
var deadline: Long = 0L
- var cont: CancellableContinuation<Unit>? = null
+ val chan: Channel<Unit> = Channel(Channel.CONFLATED)
private var initialized: Boolean = false
internal val job: Job = launch {
@@ -443,6 +449,7 @@ class SimpleVirtDriver(
server = server.copy(state = serverState)
availableMemory += server.flavor.memorySize
vms.remove(this)
+ vmStopped(server)
eventFlow.emit(HypervisorEvent.VmsUpdated(this@SimpleVirtDriver, vms.size, availableMemory))
events.close()
}
@@ -466,15 +473,12 @@ class SimpleVirtDriver(
// Wait until the burst has been run or the coroutine is cancelled
try {
schedulingQueue.send(SchedulerCommand.Schedule(this, requests))
- suspendCancellableCoroutine<Unit> { cont = it }
+ chan.receive()
} catch (e: CancellationException) {
// Deschedule the VM
- withContext(NonCancellable) {
- requests.forEach { it.isCancelled = true }
- schedulingQueue.send(SchedulerCommand.Interrupt)
- suspendCancellableCoroutine<Unit> { cont = it }
- }
-
+ requests.forEach { it.isCancelled = true }
+ schedulingQueue.send(SchedulerCommand.Interrupt)
+ chan.receive()
e.assertFailure()
}
}
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/SimpleVirtProvisioningService.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/SimpleVirtProvisioningService.kt
index 6200ad7c..5ed58fee 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/SimpleVirtProvisioningService.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/SimpleVirtProvisioningService.kt
@@ -55,7 +55,10 @@ class SimpleVirtProvisioningService(
*/
private val activeImages: MutableSet<ImageView> = mutableSetOf()
- override val hypervisorEvents: Flow<HypervisorEvent> = EventFlow()
+ public var submittedVms = 0L
+ public var queuedVms = 0L
+ public var runningVms = 0L
+ public var finishedVms = 0L
/**
* The allocation logic to use.
@@ -87,6 +90,8 @@ class SimpleVirtProvisioningService(
image: Image,
flavor: Flavor
): Server = withContext(coroutineContext) {
+ submittedVms++
+ queuedVms++
suspendCancellableCoroutine<Server> { cont ->
val vmInstance = ImageView(name, image, flavor, cont)
incomingImages += vmInstance
@@ -145,6 +150,8 @@ class SimpleVirtProvisioningService(
)
imageInstance.server = server
imageInstance.continuation.resume(server)
+ queuedVms--
+ runningVms++
activeImages += imageInstance
server.events
@@ -152,6 +159,9 @@ class SimpleVirtProvisioningService(
when (event) {
is ServerEvent.StateChanged -> {
if (event.server.state == ServerState.SHUTOFF) {
+ runningVms--
+ finishedVms++
+
activeImages -= imageInstance
selectedHv.provisionedCores -= server.flavor.cpuCount
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/VirtProvisioningService.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/VirtProvisioningService.kt
index 550048a4..695f7274 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/VirtProvisioningService.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/service/VirtProvisioningService.kt
@@ -18,11 +18,6 @@ interface VirtProvisioningService {
val allocationPolicy: AllocationPolicy
/**
- * The events emitted by the hypervisors.
- */
- public val hypervisorEvents: Flow<HypervisorEvent>
-
- /**
* Obtain the active hypervisors for this provisioner.
*/
public suspend fun drivers(): Set<VirtDriver>
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
deleted file mode 100644
index 04056394..00000000
--- a/opendc/opendc-core/src/main/kotlin/com/atlarge/opendc/core/workload/PerformanceInterferenceModel.kt
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.atlarge.opendc.core.workload
-
-import com.atlarge.opendc.core.resource.Resource
-import kotlin.random.Random
-
-/**
- * Meta-data key for the [PerformanceInterferenceModel] of an image.
- */
-const val IMAGE_PERF_INTERFERENCE_MODEL = "image:performance-interference"
-
-/**
- * Performance Interference Model describing the variability incurred by different sets of workloads if colocated.
- *
- * @param items The [PerformanceInterferenceModelItem]s that make up this model.
- */
-data class PerformanceInterferenceModel(
- val items: Set<PerformanceInterferenceModelItem>,
- val random: Random = Random(0)
-) {
- private var intersectingItems: List<PerformanceInterferenceModelItem> = emptyList()
- private var comparator = Comparator<PerformanceInterferenceModelItem> { lhs, rhs ->
- var cmp = lhs.performanceScore.compareTo(rhs.performanceScore)
- if (cmp != 0) {
- return@Comparator cmp
- }
-
- cmp = lhs.minServerLoad.compareTo(rhs.minServerLoad)
- if (cmp != 0) {
- return@Comparator cmp
- }
-
- 0
- }
-
- fun computeIntersectingItems(colocatedWorkloads: Set<Resource>) {
- val colocatedWorkloadIds = colocatedWorkloads.map { it.name }
- intersectingItems = items.filter { item ->
- colocatedWorkloadIds.intersect(item.workloadNames).size > 1
- }.sortedWith(comparator)
- }
-
- fun apply(currentServerLoad: Double): Double {
- if (intersectingItems.isEmpty()) {
- return 1.0
- }
- val score = intersectingItems
- .firstOrNull { it.minServerLoad <= currentServerLoad }
-
- // Apply performance penalty to (on average) only one of the VMs
- return if (score != null && random.nextInt(score.workloadNames.size) == 0) {
- score.performanceScore
- } else {
- 1.0
- }
- }
-}
-
-/**
- * Model describing how a specific set of workloads causes performance variability for each workload.
- *
- * @param workloadNames The names of the workloads that together cause performance variability for each workload in the set.
- * @param minServerLoad The minimum total server load at which this interference is activated and noticeable.
- * @param performanceScore The performance score that should be applied to each workload's performance. 1 means no
- * influence, <1 means that performance degrades, and >1 means that performance improves.
- */
-data class PerformanceInterferenceModelItem(
- val workloadNames: Set<String>,
- val minServerLoad: Double,
- val performanceScore: Double
-) {
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (javaClass != other?.javaClass) return false
-
- other as PerformanceInterferenceModelItem
-
- if (workloadNames != other.workloadNames) return false
-
- return true
- }
-
- override fun hashCode(): Int = workloadNames.hashCode()
-}
diff --git a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt
index 02a982dc..464f4fc6 100644
--- a/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt
+++ b/opendc/opendc-experiments-sc20/src/main/kotlin/com/atlarge/opendc/experiments/sc20/Sc20Monitor.kt
@@ -34,6 +34,10 @@ class Sc20Monitor(
.name("hostState").type().stringType().noDefault()
.name("hostUsage").type().doubleType().noDefault()
.name("powerDraw").type().doubleType().noDefault()
+ .name("totalSubmittedVms").type().longType().noDefault()
+ .name("totalQueuedVms").type().longType().noDefault()
+ .name("totalRunningVms").type().longType().noDefault()
+ .name("totalFinishedVms").type().longType().noDefault()
.endRecord()
private val writer = AvroParquetWriter.builder<GenericData.Record>(Path(destination))
.withSchema(schema)
@@ -58,6 +62,10 @@ class Sc20Monitor(
0.0,
0,
server,
+ 0,
+ 0,
+ 0,
+ 0,
duration
)
}
@@ -77,6 +85,10 @@ class Sc20Monitor(
cpuDemand: Double,
numberOfDeployedImages: Int,
hostServer: Server,
+ submittedVms: Long,
+ queuedVms: Long,
+ runningVms: Long,
+ finishedVms: Long,
duration: Long = 5 * 60 * 1000L
) {
// Assume for now that the host is not virtualized and measure the current power draw
@@ -98,6 +110,10 @@ class Sc20Monitor(
record.put("hostState", hostServer.state)
record.put("hostUsage", usage)
record.put("powerDraw", powerDraw)
+ record.put("totalSubmittedVms", submittedVms)
+ record.put("totalQueuedVms", queuedVms)
+ record.put("totalRunningVms", runningVms)
+ record.put("totalFinishedVms", finishedVms)
writer.write(record)
}
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 f3b5061c..08815720 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
@@ -204,7 +204,11 @@ fun main(args: Array<String>) {
event.cpuUsage,
event.cpuDemand,
event.numberOfDeployedImages,
- event.hostServer
+ event.hostServer,
+ scheduler.submittedVms,
+ scheduler.queuedVms,
+ scheduler.runningVms,
+ scheduler.finishedVms
)
}
}
@@ -229,15 +233,14 @@ fun main(args: Array<String>) {
null
}
+ var submitted = 0L
val finish = Channel<Unit>(Channel.RENDEZVOUS)
- var submitted = 0
- var finished = 0
val reader = Sc20TraceReader(File(traceDirectory), performanceInterferenceModel, getSelectedVmList())
while (reader.hasNext()) {
val (time, workload) = reader.next()
- delay(max(0, time - simulationContext.clock.millis()))
submitted++
+ delay(max(0, time - simulationContext.clock.millis()))
launch {
chan.send(Unit)
val server = scheduler.deploy(
@@ -250,12 +253,7 @@ fun main(args: Array<String>) {
if (it is ServerEvent.StateChanged)
monitor.onVmStateChanged(it.server)
- // Detect whether the VM has finished running
- if (it.server.state == ServerState.SHUTOFF) {
- finished++
- }
-
- if (finished == submitted && !reader.hasNext()) {
+ if (scheduler.submittedVms == submitted && scheduler.runningVms <= 1 && !reader.hasNext()) {
finish.send(Unit)
}
}
diff --git a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/PerformanceInterferenceModelReader.kt b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/PerformanceInterferenceModelReader.kt
index f9ebba3d..a653e643 100644
--- a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/PerformanceInterferenceModelReader.kt
+++ b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/PerformanceInterferenceModelReader.kt
@@ -24,7 +24,7 @@
package com.atlarge.opendc.format.trace
-import com.atlarge.opendc.core.workload.PerformanceInterferenceModel
+import com.atlarge.opendc.compute.core.workload.PerformanceInterferenceModel
import java.io.Closeable
/**
diff --git a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20PerformanceInterferenceReader.kt b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20PerformanceInterferenceReader.kt
index daa1fdf8..8562cefe 100644
--- a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20PerformanceInterferenceReader.kt
+++ b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/sc20/Sc20PerformanceInterferenceReader.kt
@@ -24,13 +24,14 @@
package com.atlarge.opendc.format.trace.sc20
-import com.atlarge.opendc.core.workload.PerformanceInterferenceModel
-import com.atlarge.opendc.core.workload.PerformanceInterferenceModelItem
+import com.atlarge.opendc.compute.core.workload.PerformanceInterferenceModel
+import com.atlarge.opendc.compute.core.workload.PerformanceInterferenceModelItem
import com.atlarge.opendc.format.trace.PerformanceInterferenceModelReader
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import java.io.InputStream
+import java.util.TreeSet
/**
* A parser for the JSON performance interference setup files used for the SC20 paper.
@@ -49,7 +50,7 @@ class Sc20PerformanceInterferenceReader(input: InputStream, mapper: ObjectMapper
return PerformanceInterferenceModel(
performanceInterferenceModel.map { item ->
PerformanceInterferenceModelItem(
- item.vms.toSet(),
+ TreeSet(item.vms),
item.minServerLoad,
item.performanceScore
)
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 c40cb039..96daa2ce 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
@@ -28,8 +28,8 @@ import com.atlarge.opendc.compute.core.image.FlopsHistoryFragment
import com.atlarge.opendc.compute.core.image.VmImage
import com.atlarge.opendc.compute.core.workload.VmWorkload
import com.atlarge.opendc.core.User
-import com.atlarge.opendc.core.workload.IMAGE_PERF_INTERFERENCE_MODEL
-import com.atlarge.opendc.core.workload.PerformanceInterferenceModel
+import com.atlarge.opendc.compute.core.workload.IMAGE_PERF_INTERFERENCE_MODEL
+import com.atlarge.opendc.compute.core.workload.PerformanceInterferenceModel
import com.atlarge.opendc.format.trace.TraceEntry
import com.atlarge.opendc.format.trace.TraceReader
import java.io.BufferedReader
@@ -127,9 +127,10 @@ class Sc20TraceReader(
val uuid = UUID(0, idx.toLong())
- val relevantPerformanceInterferenceModelItems = PerformanceInterferenceModel(
- performanceInterferenceModel.items.filter { it.workloadNames.contains(vmId) }.toSet()
- )
+ val relevantPerformanceInterferenceModelItems =
+ PerformanceInterferenceModel(
+ performanceInterferenceModel.items.filter { it.workloadNames.contains(vmId) }.toSet()
+ )
val vmWorkload = VmWorkload(
uuid, "VM Workload $vmId", UnnamedUser,
diff --git a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/vm/VmTraceReader.kt b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/vm/VmTraceReader.kt
index fbe77654..be9ddfaa 100644
--- a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/vm/VmTraceReader.kt
+++ b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/trace/vm/VmTraceReader.kt
@@ -28,8 +28,8 @@ import com.atlarge.opendc.compute.core.image.FlopsHistoryFragment
import com.atlarge.opendc.compute.core.image.VmImage
import com.atlarge.opendc.compute.core.workload.VmWorkload
import com.atlarge.opendc.core.User
-import com.atlarge.opendc.core.workload.IMAGE_PERF_INTERFERENCE_MODEL
-import com.atlarge.opendc.core.workload.PerformanceInterferenceModel
+import com.atlarge.opendc.compute.core.workload.IMAGE_PERF_INTERFERENCE_MODEL
+import com.atlarge.opendc.compute.core.workload.PerformanceInterferenceModel
import com.atlarge.opendc.format.trace.TraceEntry
import com.atlarge.opendc.format.trace.TraceReader
import java.io.BufferedReader
@@ -123,9 +123,10 @@ class VmTraceReader(
val uuid = UUID(0L, vmId)
- val relevantPerformanceInterferenceModelItems = PerformanceInterferenceModel(
- performanceInterferenceModel.items.filter { it.workloadNames.contains(vmId.toString()) }.toSet()
- )
+ val relevantPerformanceInterferenceModelItems =
+ PerformanceInterferenceModel(
+ performanceInterferenceModel.items.filter { it.workloadNames.contains(vmId.toString()) }.toSet()
+ )
val vmWorkload = VmWorkload(
uuid, "VM Workload $vmId", UnnamedUser,