diff options
Diffstat (limited to 'opendc-compute/opendc-compute-simulator/src/main/kotlin')
3 files changed, 135 insertions, 41 deletions
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt index fc40fac0..240d21d5 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt @@ -39,6 +39,7 @@ import java.util.SplittableRandom import java.util.random.RandomGenerator public enum class ComputeSchedulerEnum { + Smart, Mem, MemInv, CoreMem, @@ -81,6 +82,9 @@ public fun createPrefabComputeScheduler( /** * Create a [ComputeScheduler] for the experiment. + * I have changed this to use the new SmartScheduler. + * + * @author Mateusz Kwiatkowski */ public fun createPrefabComputeScheduler( name: ComputeSchedulerEnum, @@ -92,6 +96,8 @@ public fun createPrefabComputeScheduler( val ramAllocationRatio = 1.0 val gpuAllocationRatio = 1.0 return when (name) { + ComputeSchedulerEnum.Smart -> + SmartScheduler() ComputeSchedulerEnum.Mem -> FilterScheduler( filters = listOf(VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)), diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/SmartScheduler.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/SmartScheduler.kt index 0edd97cf..42b652a7 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/SmartScheduler.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/SmartScheduler.kt @@ -1,69 +1,158 @@ -/* - * Copyright (c) 2021 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 org.opendc.compute.simulator.scheduler + import org.opendc.common.utils.HTTPClient +import org.opendc.compute.simulator.scheduler.filters.HostFilter import org.opendc.compute.simulator.service.HostView import org.opendc.compute.simulator.service.ServiceTask +import java.util.SplittableRandom +import java.util.random.RandomGenerator +/** + * A scheduler that is able to cooperate with a digital twin. + * Currently, this is hardcoded. + * Important: the random seed can aid you in finding good standard deviation measure. + * The scheduling significantly affects downtime. + * + * @author Mateusz Kwiatkowski + */ public class SmartScheduler : ComputeScheduler { + private val maxTimesSkipped: Int = 7 + private val random: RandomGenerator = SplittableRandom(128) + // We will use a priority queue. + private val hostsQueue = List(100, { mutableListOf<HostView>() }) + private var minAvailableHost = 0 + private var numHosts = 0 private val client = HTTPClient.getInstance() - // the point is that a smart scheduler listens for suggestions from the - // digital twin - // and here is where you change your actions based on the result from the DT - // predictive analytics is going to be much easier to do. - // you will completely overcome the overhead of having to tap-into - // the digital twin mid-through the simulation/in between two hosts being scheduled - // i.e., the normal simulation will NOT have to wait. - // predictive analytics will overcome the problem of the scheduling time overhead override fun addHost(host: HostView) { - TODO("Not yet implemented") + val zeroQueue = hostsQueue[0] + zeroQueue.add(host) + host.priorityIndex = 0; + host.listIndex = zeroQueue.size - 1 + numHosts++ + minAvailableHost = 0 } override fun removeHost(host: HostView) { - TODO("Not yet implemented") + val priorityIdx = host.priorityIndex + val listIdx = host.listIndex + val chosenList = hostsQueue[priorityIdx] + + if (chosenList.size == 1) { + chosenList.removeLast() + if (listIdx == minAvailableHost) { + for (i in minAvailableHost + 1..hostsQueue.lastIndex) { + if (hostsQueue[i].size > 0) { + minAvailableHost = i + break + } + } + } + } else { + val lastItem = chosenList.removeLast() + chosenList[listIdx] = lastItem + lastItem.listIndex = listIdx + } + numHosts-- } override fun updateHost(host: HostView) { - TODO("Not yet implemented") + // No-op + } override fun setHostEmpty(hostView: HostView) { - TODO("Not yet implemented") + // No-op } override fun select(iter: MutableIterator<SchedulingRequest>): SchedulingResult { - TODO("Not yet implemented") - // Here be the API calls using HTTP between the other OpenDC - // You need to specify how much time do you have to make the prediction between receiving a time and putting onto a host - return SchedulingResult(SchedulingResultType.EMPTY) + client?.checkForInsights() + + if (numHosts == 0) { + return SchedulingResult(SchedulingResultType.FAILURE) + } + + val maxIters = 10000 + var numIters = 0 + + var chosenList: MutableList<HostView>? = null + var chosenHost: HostView? = null + + var result: SchedulingResult? = null + taskloop@ for (req in iter) { + if (req.isCancelled) { + iter.remove() + continue + } + + numIters++ + if (numIters > maxIters) { + return SchedulingResult(SchedulingResultType.EMPTY) + } + + for (chosenListIndex in minAvailableHost until hostsQueue.size) { + chosenList = hostsQueue[chosenListIndex] + for (host in chosenList) { + // Here be filtering, but for now we remove it completely. + iter.remove() + chosenHost = host + result = SchedulingResult(SchedulingResultType.SUCCESS, host, req) + break@taskloop + } + } + req.timesSkipped++ + } + + if (result == null) return SchedulingResult(SchedulingResultType.EMPTY) // No tasks to schedule that fit + + // Bookkeeping to maintain the calendar priority queue + if (chosenList!!.size == 1) { + chosenList.removeLast() + minAvailableHost++ + } else { + val listIdx = chosenHost!!.listIndex + // Not using removeLast here as it would cause problems during swapping + // if chosenHost is lastItem + val lastItem = chosenList.last() + chosenList[listIdx] = lastItem + lastItem.listIndex = listIdx + chosenList.removeLast() + } + + val nextList = hostsQueue[chosenHost!!.priorityIndex + 1] + nextList.add(chosenHost) + chosenHost.priorityIndex++ + chosenHost.listIndex = nextList.size - 1 + + return result } override fun removeTask( task: ServiceTask, - host: HostView?, + host: HostView? ) { - TODO("Not yet implemented") + if (host == null) return + + val priorityIdx = host.priorityIndex + val listIdx = host.listIndex + val chosenList = hostsQueue[priorityIdx] + val nextList = hostsQueue[priorityIdx - 1] + + if (chosenList.size == 1) { + chosenList.removeLast() + } else { + val lastItem = chosenList.last() + chosenList[listIdx] = lastItem + lastItem.listIndex = listIdx + chosenList.removeLast() + } + + nextList.add(host) + host.priorityIndex-- + host.listIndex = nextList.size - 1 + if (priorityIdx == minAvailableHost) { + minAvailableHost-- + } } } diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/KafkaComputeMonitor.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/KafkaComputeMonitor.kt index ddd4a28a..d158f782 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/KafkaComputeMonitor.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/telemetry/KafkaComputeMonitor.kt @@ -51,7 +51,6 @@ public class KafkaComputeMonitor : ComputeMonitor { .setDowntime(reader.downtime.toDouble()) .build() this.send(packet) - } catch (e: Exception) { println("${e.message}") } |
