Skip to content

Commit fb7d301

Browse files
authored
Shift task execution to the valley of carbon emissions (#323)
* Move shifted task execution to the valley of carbon emissions * Remove error from compute service * spotless apply * Run scheduling cycle everytime carbon intensity updates
1 parent 702b739 commit fb7d301

File tree

4 files changed

+49
-10
lines changed

4 files changed

+49
-10
lines changed

opendc-compute/opendc-compute-simulator/src/main/java/org/opendc/compute/simulator/service/ComputeService.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
import org.opendc.compute.simulator.scheduler.SchedulingResultType;
5656
import org.opendc.compute.simulator.telemetry.ComputeMetricReader;
5757
import org.opendc.compute.simulator.telemetry.SchedulerStats;
58+
import org.opendc.simulator.compute.power.CarbonModel;
59+
import org.opendc.simulator.compute.power.CarbonReceiver;
5860
import org.opendc.simulator.compute.power.SimPowerSource;
5961
import org.opendc.simulator.compute.power.batteries.SimBattery;
6062
import org.opendc.simulator.compute.workload.Workload;
@@ -64,7 +66,7 @@
6466
/**
6567
* The {@link ComputeService} hosts the API implementation of the OpenDC Compute Engine.
6668
*/
67-
public final class ComputeService implements AutoCloseable {
69+
public final class ComputeService implements AutoCloseable, CarbonReceiver {
6870
private static final Logger LOGGER = LoggerFactory.getLogger(ComputeService.class);
6971

7072
/**
@@ -433,6 +435,14 @@ void delete(ServiceTask task) {
433435
taskById.remove(task.getUid());
434436
}
435437

438+
public void updateCarbonIntensity(double newCarbonIntensity) {
439+
requestSchedulingCycle();
440+
}
441+
442+
public void setCarbonModel(CarbonModel carbonModel) {}
443+
444+
public void removeCarbonModel(CarbonModel carbonModel) {}
445+
436446
/**
437447
* Indicate that a new scheduling cycle is needed due to a change to the service's state.
438448
*/
@@ -449,12 +459,12 @@ private void requestSchedulingCycle() {
449459
* Run a single scheduling iteration.
450460
*/
451461
private void doSchedule() {
452-
453462
for (Iterator<SchedulingRequest> iterator = taskQueue.iterator();
454463
iterator.hasNext();
455464
iterator = taskQueue.iterator()) {
456465
final SchedulingResult result = scheduler.select(iterator);
457466
if (result.getResultType() == SchedulingResultType.EMPTY) {
467+
458468
break;
459469
}
460470
final HostView hv = result.getHost();

opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/provisioner/HostsProvisioningStep.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ public class HostsProvisioningStep internal constructor(
8080
for (receiver in carbonReceivers) {
8181
carbonModel.addReceiver(receiver)
8282
}
83+
val computeService = ctx.registry.resolve(serviceDomain, ComputeService::class.java)!!
84+
carbonModel.addReceiver(computeService)
8385
}
8486

8587
if (cluster.battery != null) {

opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/ComputeSchedulers.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public enum class ComputeSchedulerEnum {
4747
Random,
4848
TaskNumMemorizing,
4949
Timeshift,
50+
TimeshiftNoPeak,
5051
}
5152

5253
public fun createComputeScheduler(
@@ -128,5 +129,14 @@ public fun createComputeScheduler(
128129
clock = clock,
129130
random = SplittableRandom(seeder.nextLong()),
130131
)
132+
ComputeSchedulerEnum.TimeshiftNoPeak ->
133+
TimeshiftScheduler(
134+
filters = listOf(ComputeFilter(), VCpuFilter(cpuAllocationRatio), RamFilter(ramAllocationRatio)),
135+
weighers = listOf(RamWeigher(multiplier = 1.0)),
136+
windowSize = 168,
137+
clock = clock,
138+
peakShift = false,
139+
random = SplittableRandom(seeder.nextLong()),
140+
)
131141
}
132142
}

opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/scheduler/TimeshiftScheduler.kt

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class TimeshiftScheduler(
4141
private val windowSize: Int,
4242
private val clock: InstantSource,
4343
private val subsetSize: Int = 1,
44+
private val peakShift: Boolean = true,
4445
private val random: RandomGenerator = SplittableRandom(0),
4546
) : ComputeScheduler, CarbonReceiver {
4647
/**
@@ -54,11 +55,7 @@ public class TimeshiftScheduler(
5455

5556
private val pastCarbonIntensities = LinkedList<Double>()
5657
private var carbonRunningSum = 0.0
57-
58-
private var carbonIntensity = 0.0
59-
60-
// private var lowerCarbonIntensity = 0.0
61-
private var thresholdCarbonIntensity = 0.0
58+
private var isLowCarbon = false
6259

6360
override fun addHost(host: HostView) {
6461
hosts.add(host)
@@ -78,7 +75,7 @@ public class TimeshiftScheduler(
7875

7976
val task = req.task
8077

81-
if (carbonIntensity > thresholdCarbonIntensity) {
78+
if (!isLowCarbon) {
8279
if (task.nature.deferrable) {
8380
val currentTime = clock.instant()
8481
val estimatedCompletion = currentTime.plus(task.duration)
@@ -146,13 +143,33 @@ public class TimeshiftScheduler(
146143
) {}
147144

148145
override fun updateCarbonIntensity(newCarbonIntensity: Double) {
149-
this.carbonIntensity = newCarbonIntensity
146+
val previousCarbonIntensity =
147+
if (this.pastCarbonIntensities.isEmpty()) {
148+
0.0
149+
} else {
150+
this.pastCarbonIntensities.last()
151+
}
150152
this.pastCarbonIntensities.addLast(newCarbonIntensity)
151153
this.carbonRunningSum += newCarbonIntensity
152154
if (this.pastCarbonIntensities.size > this.windowSize) {
153155
this.carbonRunningSum -= this.pastCarbonIntensities.removeFirst()
154156
}
155-
this.thresholdCarbonIntensity = this.carbonRunningSum / this.pastCarbonIntensities.size
157+
158+
val thresholdCarbonIntensity = this.carbonRunningSum / this.pastCarbonIntensities.size
159+
160+
if (!peakShift) {
161+
isLowCarbon = newCarbonIntensity < thresholdCarbonIntensity
162+
return
163+
}
164+
165+
isLowCarbon = (
166+
(newCarbonIntensity < thresholdCarbonIntensity) &&
167+
(newCarbonIntensity > previousCarbonIntensity)
168+
) ||
169+
(
170+
(newCarbonIntensity < 1.2 * thresholdCarbonIntensity) &&
171+
isLowCarbon
172+
)
156173
}
157174

158175
override fun setCarbonModel(carbonModel: CarbonModel?) {}

0 commit comments

Comments
 (0)