summaryrefslogtreecommitdiff
path: root/opendc/opendc-compute
diff options
context:
space:
mode:
authorGeorgios Andreadis <g.andreadis@student.tudelft.nl>2020-02-28 13:29:55 +0100
committerGeorgios Andreadis <g.andreadis@student.tudelft.nl>2020-02-28 13:29:55 +0100
commit0c19b32433e2086e72e0d22595f4daa6ef04b64b (patch)
tree149b03d55d90a2047a428427c509233e69ddd19f /opendc/opendc-compute
parentedc5234be4440499b15450f66c9e699f8ed8cc71 (diff)
parent6c295a937834cf0e5b061bade1dddf66e4997648 (diff)
Merge branch 'bug/2.x-vm-units' into 'feat/2.x'
bug: Fix timing issues to to unit differences See merge request opendc/opendc-simulator!32
Diffstat (limited to 'opendc/opendc-compute')
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsHistoryFragment.kt2
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/VmImage.kt6
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt9
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/HypervisorVirtDriver.kt1
-rw-r--r--opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/VmSchedulerImpl.kt18
5 files changed, 24 insertions, 12 deletions
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsHistoryFragment.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsHistoryFragment.kt
index 320c09ff..92c0ab0c 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsHistoryFragment.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsHistoryFragment.kt
@@ -1,3 +1,3 @@
package com.atlarge.opendc.compute.core.image
-data class FlopsHistoryFragment(val tick: Long, val flops: Long, val duration: Long)
+data class FlopsHistoryFragment(val tick: Long, val flops: Long, val duration: Long, val usage: Double)
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/VmImage.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/VmImage.kt
index 257b6149..4e8162ec 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/VmImage.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/VmImage.kt
@@ -1,5 +1,6 @@
package com.atlarge.opendc.compute.core.image
+import com.atlarge.odcsim.processContext
import com.atlarge.opendc.compute.core.execution.ServerContext
import com.atlarge.opendc.core.resource.TagContainer
import kotlinx.coroutines.coroutineScope
@@ -24,11 +25,10 @@ class VmImage(
} else {
val cores = min(this.cores, ctx.server.flavor.cpuCount)
val req = fragment.flops / cores
-
coroutineScope {
for (cpu in ctx.cpus.take(cores)) {
- val usage = req / (fragment.duration * 1_000_000L).toDouble()
- launch { cpu.run(req, usage, fragment.tick + fragment.duration) }
+ val usage = req / (fragment.usage * 1_000_000L)
+ launch { cpu.run(req, usage, processContext.clock.millis() + fragment.duration) }
}
}
}
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt
index 202c30e9..b6d74cde 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt
@@ -130,16 +130,19 @@ public class SimpleBareMetalDriver(
private data class ProcessorContextImpl(override val info: ProcessingUnit) : ProcessorContext {
override suspend fun run(burst: Long, maxUsage: Double, deadline: Long): Long {
val start = processContext.clock.millis()
- val usage = min(maxUsage, info.clockRate)
+ val usage = min(maxUsage, info.clockRate) * 1_000_000 // Usage from MHz to Hz
try {
- val duration = min(max(0, deadline - start), ceil(burst / usage).toLong())
+ val duration = min(
+ max(0, deadline - start), // Determine duration between now and deadline
+ ceil(burst / usage * 1000).toLong() // Convert from seconds to milliseconds
+ )
delay(duration)
} catch (_: CancellationException) {
// On cancellation, we compute and return the remaining burst
}
val end = processContext.clock.millis()
- val granted = ceil((end - start) * usage * 1_000_000).toLong()
+ val granted = ceil((end - start) / 1000.0 * usage).toLong()
return max(0, burst - granted)
}
}
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/HypervisorVirtDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/HypervisorVirtDriver.kt
index 65ec75a2..c0d5fe0f 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/HypervisorVirtDriver.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/HypervisorVirtDriver.kt
@@ -61,6 +61,7 @@ class HypervisorVirtDriver(
if (memoryAvailable - requiredMemory < 0) {
throw InsufficientMemoryOnServerException()
}
+ require(flavor.cpuCount <= hostContext.server.flavor.cpuCount) { "Machine does not fit" }
val server = Server(UUID.randomUUID(), "<unnamed>", emptyMap(), flavor, image, ServerState.BUILD)
memoryAvailable -= requiredMemory
diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/VmSchedulerImpl.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/VmSchedulerImpl.kt
index dfed3d58..0b172c61 100644
--- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/VmSchedulerImpl.kt
+++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/VmSchedulerImpl.kt
@@ -55,8 +55,12 @@ public class VmSchedulerImpl(
override fun createVirtualCpus(flavor: Flavor): List<ProcessorContext> {
// TODO At the moment, the first N cores get filled the first. Distribute over all cores instead
- return cpus.asSequence()
+ require(flavor.cpuCount <= cpus.size) { "Flavor cannot fit on machine" }
+
+ return cpus
+ .asSequence()
.take(flavor.cpuCount)
+ .sortedBy { it.vcpus.size }
.map { VirtualProcessorContext(it) }
.toList()
}
@@ -96,7 +100,7 @@ public class VmSchedulerImpl(
vcpu.actualUsage = min(vcpu.requestedUsage, info.clockRate / vcpus.size)
// The duration that we want to run is that of the shortest request from a vCPU
- duration = min(duration, ceil(vcpu.requestedBurst / vcpu.actualUsage).toLong())
+ duration = min(duration, ceil(vcpu.requestedBurst / (vcpu.actualUsage * 1_000_000L)).toLong())
deadline = min(deadline, vcpu.requestedDeadline)
}
@@ -104,16 +108,21 @@ public class VmSchedulerImpl(
var usage: Double = 0.0
for (vcpu in vcpus) {
- vcpu.actualBurst = (duration * vcpu.actualUsage).toLong()
+ vcpu.actualBurst = (duration * vcpu.actualUsage * 1_000_000L).toLong()
burst += vcpu.actualBurst
usage += vcpu.actualUsage
}
+ // Ignore time slice if no work to request
+ if (burst <= 0L) {
+ return@launch
+ }
+
// We run the total burst on the host processor. Note that this call may be cancelled at any moment in
// time, so not all of the burst may be executed.
val remainder = run(burst, usage, deadline)
val time = processContext.clock.millis()
- var totalGrantedBurst: Long = 0
+ val totalGrantedBurst: Long = burst - remainder
// Compute for each vCPU the
for (vcpu in vcpus) {
@@ -121,7 +130,6 @@ public class VmSchedulerImpl(
val fraction = vcpu.actualUsage / usage
// Compute the burst time that the VM was actually granted
val grantedBurst = max(0, vcpu.actualBurst - ceil(remainder * fraction).toLong())
- totalGrantedBurst += grantedBurst
// Compute remaining burst time to be executed for the request
vcpu.requestedBurst = max(0, vcpu.requestedBurst - grantedBurst)