From f13cda61c142ff3d1a2e75de2b05667bdb3ab3ae Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 28 Feb 2020 15:59:14 +0100 Subject: refactor: Create distinction between CPU node and core This change updates the terminology in the `opendc-compute` module to make a distinction between CPU node and CPU core, where we primarly work with CPU cores. However, if needed, we also provide information for the different CPU nodes. --- .../atlarge/opendc/compute/core/ProcessingNode.kt | 40 ++++++++++++++++++++++ .../atlarge/opendc/compute/core/ProcessingUnit.kt | 18 ++++------ .../compute/core/image/FlopsApplicationImage.kt | 2 +- .../compute/metal/driver/SimpleBareMetalDriver.kt | 15 ++++---- .../virt/driver/hypervisor/VmSchedulerImpl.kt | 2 +- .../metal/driver/SimpleBareMetalDriverTest.kt | 7 ++-- .../metal/service/SimpleProvisioningServiceTest.kt | 6 +++- .../virt/driver/hypervisor/HypervisorTest.kt | 6 +++- .../environment/sc18/Sc18EnvironmentReader.kt | 13 +++++-- .../environment/sc20/Sc20EnvironmentReader.kt | 13 +++++-- 10 files changed, 89 insertions(+), 33 deletions(-) create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingNode.kt (limited to 'opendc') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingNode.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingNode.kt new file mode 100644 index 00000000..91f5dde9 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingNode.kt @@ -0,0 +1,40 @@ +/* + * 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 + +/** + * A processing node/package/socket containing possibly several CPU cores. + * + * @property vendor The vendor string of the processor node. + * @property modelName The name of the processor node. + * @property arch The micro-architecture of the processor node. + * @property coreCount The number of logical CPUs in the processor node. + */ +data class ProcessingNode( + val vendor: String, + val arch: String, + val modelName: String, + val coreCount: Int +) diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingUnit.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingUnit.kt index 945b7061..dbf6d824 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingUnit.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingUnit.kt @@ -25,18 +25,14 @@ package com.atlarge.opendc.compute.core /** - * A processing unit of a compute resource, either virtual or physical. + * A single logical compute unit of processor node, either virtual or physical. * - * @property vendor The vendor string of the cpu. - * @property modelName The name of the cpu model. - * @property arch The architecture of the CPU. - * @property clockRate The clock speed of the cpu in MHz. - * @property cores The number of logical cores in the cpu. + * @property node The processing node containing the CPU core. + * @property id The identifier of the CPU core within the processing node. + * @property frequency The clock rate of the CPU. */ public data class ProcessingUnit( - public val vendor: String, - public val modelName: String, - public val arch: String, - public val clockRate: Double, - public val cores: Int + public val node: ProcessingNode, + public val id: Int, + public val frequency: Double ) diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsApplicationImage.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsApplicationImage.kt index 3576b488..de429d41 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsApplicationImage.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsApplicationImage.kt @@ -65,7 +65,7 @@ class FlopsApplicationImage( coroutineScope { for (cpu in ctx.cpus.take(cores)) { - launch { cpu.run(req, cpu.info.clockRate * utilization, Long.MAX_VALUE) } + launch { cpu.run(req, cpu.info.frequency * utilization, Long.MAX_VALUE) } } } } 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 1adc8652..e1b7b178 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 @@ -53,14 +53,14 @@ import kotlinx.coroutines.withContext * * @param uid The unique identifier of the machine. * @param name An optional name of the machine. - * @param cpuNodes The CPU nodes/packages available to the bare metal machine. + * @param cpus The CPUs available to the bare metal machine. * @param memoryUnits The memory units in this machine. * @param domain The simulation domain the driver runs in. */ public class SimpleBareMetalDriver( uid: UUID, name: String, - val cpuNodes: List, + val cpus: List, val memoryUnits: List, private val domain: Domain ) : BareMetalDriver { @@ -77,7 +77,7 @@ public class SimpleBareMetalDriver( /** * The flavor that corresponds to this machine. */ - private val flavor = Flavor(cpuNodes.sumBy { it.cores }, memoryUnits.map { it.size }.sum()) + private val flavor = Flavor(cpus.size, memoryUnits.map { it.size }.sum()) /** * The job that is running the image. @@ -141,7 +141,7 @@ 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 = simulationContext.clock.millis() - val usage = min(maxUsage, info.clockRate) * 1_000_000 // Usage from MHz to Hz + val usage = min(maxUsage, info.frequency) * 1_000_000 // Usage from MHz to Hz try { val duration = min( @@ -161,11 +161,8 @@ public class SimpleBareMetalDriver( private val serverCtx = object : ServerManagementContext { private var initialized: Boolean = false - override val cpus: List = cpuNodes - .asSequence() - .flatMap { cpu -> - generateSequence { ProcessorContextImpl(cpu) }.take(cpu.cores) - } + override val cpus: List = this@SimpleBareMetalDriver.cpus + .map { ProcessorContextImpl(it) } .toList() override var server: Server 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 4cc5ac9e..f232d695 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 @@ -97,7 +97,7 @@ public class VmSchedulerImpl( for (vcpu in vcpus) { // Limit each vCPU to at most an equal share of the host CPU - vcpu.actualUsage = min(vcpu.requestedUsage, info.clockRate / vcpus.size) + vcpu.actualUsage = min(vcpu.requestedUsage, info.frequency / 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 * 1_000_000L)).toLong()) diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt index 6b234b73..6468a408 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt @@ -25,7 +25,7 @@ package com.atlarge.opendc.compute.metal.driver import com.atlarge.odcsim.SimulationEngineProvider -import com.atlarge.opendc.compute.core.Flavor +import com.atlarge.opendc.compute.core.ProcessingNode import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.core.Server import com.atlarge.opendc.compute.core.ServerState @@ -52,8 +52,9 @@ internal class SimpleBareMetalDriverTest { val root = system.newDomain(name = "root") root.launch { val dom = root.newDomain(name = "driver") - val flavor = Flavor(4, 0) - val driver = SimpleBareMetalDriver(UUID.randomUUID(), "test", listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4)), emptyList(), dom) + val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 4) + val cpus = List(5) { ProcessingUnit(cpuNode, it, 2400.0) } + val driver = SimpleBareMetalDriver(UUID.randomUUID(), "test", cpus, emptyList(), dom) val monitor = object : ServerMonitor { override suspend fun onUpdate(server: Server, previousState: ServerState) { diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt index 3b32b3b8..d5366552 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt @@ -25,6 +25,7 @@ package com.atlarge.opendc.compute.metal.service import com.atlarge.odcsim.SimulationEngineProvider +import com.atlarge.opendc.compute.core.ProcessingNode import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.core.Server import com.atlarge.opendc.compute.core.ServerState @@ -59,7 +60,10 @@ internal class SimpleProvisioningServiceTest { } val dom = root.newDomain("provisioner") - val driver = SimpleBareMetalDriver(UUID.randomUUID(), "test", listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4)), emptyList(), dom) + + val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 4) + val cpus = List(5) { ProcessingUnit(cpuNode, it, 2400.0) } + val driver = SimpleBareMetalDriver(UUID.randomUUID(), "test", cpus, emptyList(), dom) val provisioner = SimpleProvisioningService(dom) provisioner.create(driver) diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/HypervisorTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/HypervisorTest.kt index 002fa175..7e5a4bbe 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/HypervisorTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/virt/driver/hypervisor/HypervisorTest.kt @@ -29,6 +29,7 @@ import com.atlarge.odcsim.simulationContext import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.core.Server import com.atlarge.opendc.compute.core.Flavor +import com.atlarge.opendc.compute.core.ProcessingNode import com.atlarge.opendc.compute.core.ServerState import com.atlarge.opendc.compute.core.image.FlopsApplicationImage import com.atlarge.opendc.compute.core.monitor.ServerMonitor @@ -77,7 +78,10 @@ internal class HypervisorTest { } val driverDom = root.newDomain("driver") - val metalDriver = SimpleBareMetalDriver(UUID.randomUUID(), "test", listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2000.0, 1)), emptyList(), driverDom) + + val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 4) + val cpus = List(5) { ProcessingUnit(cpuNode, it, 2000.0) } + val metalDriver = SimpleBareMetalDriver(UUID.randomUUID(), "test", cpus, emptyList(), driverDom) metalDriver.init(monitor) metalDriver.setImage(vmm) diff --git a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/environment/sc18/Sc18EnvironmentReader.kt b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/environment/sc18/Sc18EnvironmentReader.kt index 8898ddc7..942a8c72 100644 --- a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/environment/sc18/Sc18EnvironmentReader.kt +++ b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/environment/sc18/Sc18EnvironmentReader.kt @@ -27,6 +27,7 @@ package com.atlarge.opendc.format.environment.sc18 import com.atlarge.odcsim.Domain import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.core.MemoryUnit +import com.atlarge.opendc.compute.core.ProcessingNode import com.atlarge.opendc.compute.metal.driver.SimpleBareMetalDriver import com.atlarge.opendc.compute.metal.service.ProvisioningService import com.atlarge.opendc.compute.metal.service.SimpleProvisioningService @@ -63,10 +64,16 @@ class Sc18EnvironmentReader(input: InputStream, mapper: ObjectMapper = jacksonOb when (roomObject) { is RoomObject.Rack -> { roomObject.machines.map { machine -> - val cores = machine.cpus.map { id -> + val cores = machine.cpus.flatMap { id -> when (id) { - 1 -> ProcessingUnit("Intel", "Core(TM) i7-6920HQ", "amd64", 4100.0, 4) - 2 -> ProcessingUnit("Intel", "Core(TM) I7-6920HQ", "amd64", 3500.0, 2) + 1 -> { + val node = ProcessingNode("Intel", "Core(TM) i7-6920HQ", "amd64", 4) + List(node.coreCount) { ProcessingUnit(node, it, 4100.0) } + } + 2 -> { + val node = ProcessingNode("Intel", "Core(TM) i7-6920HQ", "amd64", 2) + List(node.coreCount) { ProcessingUnit(node, it, 3500.0) } + } else -> throw IllegalArgumentException("The cpu id $id is not recognized") } } diff --git a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/environment/sc20/Sc20EnvironmentReader.kt b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/environment/sc20/Sc20EnvironmentReader.kt index fecba302..b33a5e93 100644 --- a/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/environment/sc20/Sc20EnvironmentReader.kt +++ b/opendc/opendc-format/src/main/kotlin/com/atlarge/opendc/format/environment/sc20/Sc20EnvironmentReader.kt @@ -26,6 +26,7 @@ package com.atlarge.opendc.format.environment.sc20 import com.atlarge.odcsim.Domain import com.atlarge.opendc.compute.core.MemoryUnit +import com.atlarge.opendc.compute.core.ProcessingNode import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.metal.driver.SimpleBareMetalDriver import com.atlarge.opendc.compute.metal.service.ProvisioningService @@ -60,10 +61,16 @@ class Sc20EnvironmentReader(input: InputStream, mapper: ObjectMapper = jacksonOb when (roomObject) { is RoomObject.Rack -> { roomObject.machines.map { machine -> - val cores = machine.cpus.map { id -> + val cores = machine.cpus.flatMap { id -> when (id) { - 1 -> ProcessingUnit("Intel", "Core(TM) i7-6920HQ", "amd64", 4100.0, 4) - 2 -> ProcessingUnit("Intel", "Core(TM) I7-6920HQ", "amd64", 3500.0, 2) + 1 -> { + val node = ProcessingNode("Intel", "Core(TM) i7-6920HQ", "amd64", 4) + List(node.coreCount) { ProcessingUnit(node, it, 4100.0) } + } + 2 -> { + val node = ProcessingNode("Intel", "Core(TM) i7-6920HQ", "amd64", 2) + List(node.coreCount) { ProcessingUnit(node, it, 3500.0) } + } else -> throw IllegalArgumentException("The cpu id $id is not recognized") } } -- cgit v1.2.3