Scheduler
|
This simulator is capable of scheduling both real-time tasks and interactive tasks. The simulator is able to model the power consumption as well as the resulting temperature of the processor. The simulator allows for selecting the task scheduling algorithm as well as the frequency governor policy.
The simulator does not schedule real tasks, but uses a model of task behavior in terms of workload and power consumption. Let's look more closely at those models.
Real-time tasks are modelled as an infinite sequence of jobs. Jobs are spawned at a regular interval. Each job is defined as a set amount of work, where every job of the same task can have the same or different (random) amount of work. Different random distributions can be used for the job's duration.
Interactive tasks are modelled as a sequence of workloads and waiting times. The waiting times model the time spent by the task waiting for user input, network, or disk access, etc. The duration of waiting time, as well as the amount of work of each workload segmentis random, following an exponential distribution.
The simulator models power consumption as the sum of static power and dynamic power. Static power has a fixed value and is consumed whenever the processor is turned on. Dynamic power depends on whichever task is running (if any) and the frequency it is running at. The simulator allows you to specify the task's power consumption relative to each other. For instance, task 0 has a power factor of 1.0, task 1 has a factor of 1.5, etc.
The simulator provides a simple, first-order, model for processor temperature. It relies on the thermal resistance and thermal capacity of the processor, and its instantaneous power consumption.
The scheduler is a set of static libraries. To install, go to the src directory and run ./buildScript.sh. This will compile the libraries as well as an example use of the simulator.
to run the simulator, go to the simulator/ directory and run the command:
As a first example, let's look at a very simple real-time scheduling problem. Let's consider two tasks. The first has a period of 15 and a worst-case execution time (WCET) of 5. The second task has a period of 20 and a WCET of 6. Both tasks are assumed to be deterministic, so that their execution time is always equal to their WCET. We want to schedule this taskset under rate-monotonic scheduling.
Let's take a look at the main function, in the file src/main.cpp
:
The first step is to create a SchedulerConfiguration object, initialized from a configuration file. This allows you to specify many simulation parameters in a configuration file instead of havnig to hard-code them in C++. Then, we create a SchedulingSimulator object. This is the main object of the simulator. Next, we can create the tasks. The easiest way is via the createRealTimeTask with four arguments:
Next, we specify the time at which the processor should turn on. This value should be less than the starting time of the tasks.
Then, the function endSimulation() is used top specify at what time the simulation should end. In this case, we get the value from the configuration file.
Finally, we start the simulation.
Once the main file written, we can build the simulator (see above). We can now edit the configuration file, located in configuration/configuration.conf
The most important field is the kind of task scheduler to use. In this case, it is rate-monotonic scheduling (rmsScheduler).
When executing the simulation with the -verbose option, a log is displayed:
it contains the list of all events, along with the time at which they occured. For instance, both tasks spawn a new job at time 0.0. At time 5.0, task with pid 0 terminates. Whenever the task scheduler is invoked, the content of the ready queue is displayed. It comprises the pid of the task as well as its amount of work. It also prints the task currently being executed (or about to be).
The first way to specify the taskset to simulate is to directly write it in C++ code, as we did in the first example.
Another way to generate tasksets is to do it randomly. First, make sure to replace the createRealTimeTask lines in the main function with the following line:
To generate the taskset randomly, you will also need to set up the configuration file as follows: In the [taskSet] section, the tasksetSource entry should be set to random, and some values need to be specified:
the utilization field lets you specify the processor utilization of the task set. nbOfTasks is the number of tasks. The simulator will then generate a taskset where tasks have random periods and wcet. Some other fields are required. The seed is the seed of the random generator that generates the taskset. This allows you to generate a different taskset by changing the seed value. By setting the priorities field to yes, the tasks will each have a different priority. This characteristic is used by some scheduling algorithms. Finally, powerSpan lets you specify the span of instantaneous power consumption of the different tasks (more on that later).
Tasksets can also be specified via a configuration file. This allows tasksets to be changed without having to recompile the simulator. Also, they provide a structured way to store or transfer taskset data.
An example of XML taskset is in the file xml/taskset.xml
In our first example, we had deterministic tasks: their execution time was always equal to their WCET. It is possible to specify a random task duration, no matter what task generation process (programatically, random, xml) you use. In the [scheduler] section of the configuration file, specify the distribution of task duration in the 'distribution' field. The possible values are:
none
the task duration is deterministic and equal to its WCETdeterministic
same as none
uniform
the task diration follows a uniform random variable. The duration will be anywhere between BCET and WCET.bernoulli
'p'
the task duration follows a Bernoulli distribution: it will be equal to WCET with probability 'p' and BCET with probability 1 - 'p'. 'p' needs to be a number between 0 and 1.For programatically generated tasksets, the BCET is specified in the createRealTimeTask
function as an optional parameter. See function Scheduler::SchedulingSimulator::createRealTimeTask()
For random-generated tasksets, random duration is not yet fully supported.
The simulator comes with several scheduling disciplines availables, and allows you to easily add additional algorithms.
The built-in scheduling disciplines are:
rmsDiscipline
Rate monotonic schedulingedfDiscipline
Earliest deadline firstfixedPriorityDiscipline
Fixed priorityfcfsDiscipline
First come first serveroundRobinDiscipline
Round robinrlDiscipline
Reinforcement learning (more on that later)To create a new scheduling algorithm, the following steps should be taken:
discipline
field of the
[scheduler] section in the configuration file.SchedulerConfiguration::getDisciplineFromFile()
in the file src/scheduler/schedulerConfiguration.cpp in order to allow your new discipline to be selected at the configuration file level. Just follow the logic of the other disciplines. You will also need to #include your header file in that file.Now, after building the simulator, you should be able to use your new algorithm just like any other scheduling discipline of the simulator.
Let's focus a bit on the interface functions you will need to implement:
getName()
This should return a name for your scheduling algorithm. It is mainly used for logging and reporting purposes.preempts()
Given an event, this function should return true if your algorithm is supposed to preempt the currently running task when that event occurs.selectNextTask()
This is the main function of your class. It should return which task of the ready queue should be run from this point on. It can also return nullptr
to signify that the processor should be idle until the next event.to be continued...
The simulator can save to file several reports, such as:
to be continued...
This simulator is a discrete-events simulator. Currently, it reacts to the following events:
StartProc
The processor turns onNewInteractiveProcess
A new interactive process startsNewJob
A real-time task starts a new jobReady
A process becomes readyWaiting
An interactive process stops execution to wait on a resourceTerminates
A job or interactive process finishesMissedDeadline
A job misses its deadlineStopSimulation
The simulation endsTimeOut
A periodic timer fires. This is an abstract class. The simulator currently implements the following kinds of TimeOut events:SchedTimeOut
A periodic event that can be used for schedulingStatsTick
...UsageUpdate
...FreqUpdate
...DummyEvent
...