 All right. So we got a fairly easy lecture today. Congratulations. You've made it over all the hard parts So today we're going to talk about finally basic scheduling, which you've kind of already done So this is just kind of formalizing it a little bit Making it into essentially questions that may appear on a quiz so preemptible Resources are kind of a generic term So any resource can either be preemptible or non preemptible and a preemptible resource Just means it can be taken away at any time and used for something else So for example, you have your CPU you can take it away Give it to another process and then take it away from that process give it to another one and so on and so forth So a resource that is preemptible you can share through scheduling so make sure everyone gets a turn essentially While a non preemptible resource cannot be taken away without at least some sort of acknowledgement Otherwise some things might go bad. For example disk base. I Can't share a hard drive. I can allocate space for it So I could say hey you can have you know a 4 gig file you can have a 4 gig file But every single process for example cannot share an entire hard drive You can't just swap it back and forth and non preemptible resources would be shared through something like Allocations and deallocation. So hey, I need space for file and then hey, I'm done with the file I can delete it and then you can go ahead and use it for something else and Then note for some like high performance computing and distributed systems. You may Actually be able to allocate the CPU so you can say hey, I'm going to grab this CPU. You cannot preempt me I will grab it for the entire D of my whatever my process and You can't take it away because I actually need that control. I need it to run as fast as possible So anyone want to name possibly another example of a non preemptible resource So if this space is one, what's another one that we constantly allocate and deallocate? More more generic memory, right? So memory is also a non preemptible resource I have to allocate it and deallocate it and of course with memory it can represent the stack to heap all that fun stuff So there's two things there is a dispatcher and a scheduler So a dispatcher is actually responsible for context switching you may see it in other resources and It's just whatever is doing the context switching and that's called a dispatcher So it's just another term you might see in your journeys through operating systems while The dispatcher does the context switching and then the scheduler is the high-level policy that decides what to context switch So it decides what processes to run at any given time And they have to work together So the scheduler runs whenever a process changes state So we're first going to consider the easiest case possible where we have non preemptible processes So a process once it starts it will get executed until it finishes So this is like the old batch systems where you just start a process it runs till it's finished And then after it's finished you can run something else So in this case if you're the scheduler you only have a decision to make when a process terminates And the CPU is free, and you just have to pick a process the next process to run and then preemptive which is kind of what we're all used to Just allows the scheduler to run at will and if you are on a Linux machine, you do uname dash V so we can even Run that so if you do uname dash V that's actually one of the terms here So this means it's a preemptive scheduler and the kernel will tell you that and then the other one Here is SMP. That's symmetric multi-processing that just means you can support multiple parallel processors, and they're all the same So the kernel will tell you what it supports. So if these options are here, it's like 99.9% of modern things So now we know what they both mean Okay, so when we discuss scheduling we have to have some way to evaluate how good our scheduler is and These are some metrics that you would want to keep track of So first you'd want to minimize waiting time and response time So as soon as you start a process, you would want to get executed or at least start execution on it as fast as possible And that lag time from when it gets You know when you say you want to run until it actually runs on the CPU The first time instant is called the response time. So that's kind of your responsiveness how you know how fast your system feels and Then waiting time is just the total amount of time that process is waiting to run while it Between when it starts and when it finishes Then if you're the scheduler you want to maximize CPU utilization as well If you have eight cores or something like that you want to be able to use all of them You don't want idle CPUs because they're not doing any useful work Then next you might want to maximize throughput So complete as many processes as possible if you only care about the absolute number of processes that finish And then finally with the last metric which is kind of at odds with all the other one is fairness Where you try to give each process, you know the same percentage of the CPU and try and be fair Then don't pick any favorites So our first scheduling policy everyone's been using it for their entire life at their food trucks Everything like that. It's first come first serve. You get in line It's a FIFO queue if you are the first in line, you are the first served and it just goes in order So that's the most basic form of scheduling and we're used to that pretty much our entire life So the first process that arrives gets the CPU and they get the CPU in the order that they arrive So it's just a FIFO queue in a rival order So these are going to we'll use Gantt charts to illustrate the schedule for arguing about all these problems and it's not as boring as you know Gantt charts for this Software or not software, but for you know engineering process courses This is actually a pretty simple one where we just care about what's happening on a single CPU So we're just assuming a single CPU so in the table here we have our processes P1 P2 P3 P4 and then the arrival time Which is when the user wants to start all the processes in this case They're all going to arrive at time equals to zero Then the burst time is just how long each process takes to execute how many time units it takes and we're just going to assume that What you can like will have an atomic time unit of one where we can't provide it up just to make things easier So burst time also the total execution time it needs is here So process one takes seven time units process two takes four process three takes one process four takes four So since they all arrive at the same time instant, we'll just assume that they arrive in the order P1 P2 P3 then P4 so if we do first come first serve at time zero We have them in that order you pick off the process that arrived first so in this case it would be P1 So we pick P1 to execute and we're assuming non preemptible processes. So it just runs until it finishes so We start P1 it takes seven time units So it will and then each bar there. It's a single CPU and one time unit per square So we it executes for seven time units here. So at t equals seven process one is done We have another decision to make we have to run either process two three or four and we just do it in the order They arrive so we Execute process two takes four time units and we execute process three after that finishes Which is only one time unit and then process four after process three finishes, which is four time units so One question you might ask is what is the average waiting time? So The average waiting time. It's just a simple average. So process one. How long did it wait? Well, it arrived at time zero and it got executed immediately. So it waited for zero time units Process three or sorry process two arrived at zero didn't start executing the time equals seven So it waited around for seven time units process three Got executed at t zero didn't start executing till t Equals 11 so it waited around for 11 time units and then process four waited around for 12 time units So if you take the average of all them if I remember my math is corrected seven and a half for all of them So the average waiting time is seven and a half time units first are three processes. So cool So let's compare that to what happens if they arrive in a different order So again all their arrival times are at t equals zero, but now To break the microtie. I'll just assume p3 arrives first and p2 then p4 then p1 So if I do the exact same again thing again and schedule them in that order at t zero I would schedule p3 Takes one time unit then I would at t1 I have to pick the next process which would be according to my order p2 So I pick it it executes for its four time units. It's done at t equals five Then I pick p4 Executes for four time units. It's done at t equals nine and then I finally finish up with p1 Which takes seven time units. So I'm done it t equals 16 So now when I look at the average waiting time So the average waiting time is the waiting time of all the processes divided by the number of processes So the waiting time for p1 it waited for nine time units, right? So it started at t equals zero and didn't start executing till t equals nine and Then p2 it waited around for only one time unit and then p3 waited around for zero time units because it executed immediately and then p4 Waited around for five time units before it started executing. So the average waiting time now if you add nine plus five plus one plus zero divided by four that's 3.75 so we reduced our waiting time by half just by changing the order Sorry just by changing the arrival order at the same time so it seems like the Arrival order that has a pretty significant impact on the average waiting time So if you want to minimize the average waiting time Instead of just doing first come first serve if you want to minimize it You do this which is just shortest job first. So instead of first come first serve You'll always Schedule the job with the shortest burst time first or the shortest total running time and again We're still assuming no preemption So Here I'm going to make it slightly harder where I have different arrival times So here I have p1 arrives at zero p2 arrives at time two p3 arrives at time Four and p4 arrives at time five So what I will do is just at the top of the little bars I'll just write on their arrival times here So this shows that p1 arrives at p0 and all the other arrival times for the processes just to make it easier to keep track of So now if I do shortest job first Well, I have to make a scheduling decision at t equals zero at t equals zero My only choice is p1 because that's the only process that's been executed So at time equals zero, I would schedule p1 and it takes seven time units and while that's executing P2 arrives and then p3 arrives and then p4 arrives now if I take all of these Processes, right? So p2 arrives before p3, but if I do shortest job first, I would prioritize p3 So piece at whenever p1 is done executing here I would prioritize p3 to run next because it has the shortest burst time It only takes one second to execute or one time unit. Sorry and then between p2 and p4. They both have the same They both have the same burst time So I'll just take them and first come first serve order because because at that point doesn't really matter and then So at t equals seven why I have to make my scheduling decision I picked the shortest job first which in this case would be p3. So I would execute that between I Would execute that for one time unit and it would be done at t equals eight So at t equals eight now I have two processes left to schedule p2 and p4 P2 became first so I would schedule that it's done at t equals 12 and Then I have p4 which would be the last process I execute and it's done at t equals 16 So now if I go through the average waiting time So that waiting time for process one was zero. So it got scheduled at Sorry, it got it arrived at t zero and then started executing at t zero So it waited around for zero time units. So it's waiting time is zero Then this is a and then for a little bit trickier. We have to find the waiting time for process two So it arrived at time equals two not zero now and then it started executing at t equals eight So it waited around for six time units and then similarly Process three arrived at t equals four start executing at t equals seven So it waited around for three time units and then p4 arrived at t equals five and didn't start executing to t equals 12 So it waited around for seven time units. So our average waiting time in this case is four All right, everyone all good with this so Much easier than threads and locks and all that right So back to yeah, yeah, so the first time is a total Number of time units it needs to execute Which realistically we won't know but we can evaluate our scheduling You know by analyzing it after the fact Yeah, so that's kind of why I said a short job first is not practical So it is provably optimal at minimizing the average wait time if you have no preemptions But of course if in real life with scheduling you will not know the burst times of each process So whenever the kernel executes your program it has no idea how long it's going to take to run so it can't It can't schedule based off that if it has no idea you might be able to like predict Past executions or predict future executions on past ones or use AI or something like that But again, it's not going to be perfect because programs do vary wildly And also there may be a problem where it's called starvation where you starve long jobs So if you do shortest job first and you have just a process that takes, you know 10,000 time units and You have a constant stream of processes that only takes like one or two or ten time units Well, if the small processes come in fast enough Then you may never actually execute the longest running process because it would be at the back of the queue essentially forever Which isn't terribly fair. Yeah Yeah, so realistically you won't know which is what makes scheduling even harder. So this is For now we get to live in the nice world where we'll know and we can use it to evaluate so typically people like Do a workload and then keep track of how long it takes and then simulated a bunch of times So that's how you would actually evaluate it, but they're like We'll get into more of it, but there's no perfect answer for a scheduler Yeah, provably, okay, it's provably optimal All right, so We can tweak it so that it run so we've been talking about non preemptible processes Of course, we know in our processes are preemptible So we can tweak it Shortest job first to deal with preemptible and we'll do something like shortest remaining time first So you assume that again, we'll just assume the minimal execution and time is one time unit so in this case for Preemptible processes shortest remaining time first is provably optimal to minimize the average waiting time So let's see what that tweak is So the tweak with shortest remaining time first it means when a process comes in you're allowed to switch The current running process and essentially context switch it out So here and throughout the whole lecture will use the same arrival times and burst times for the whole thing and see How our scheduling changes So now if we do shortest remaining time first, well Let's start at t equals zero. So at t equals zero again. We just start executing process one We have no other choice. That's the only process we can run So we would run it for two time units until process two comes on So at the at t equals two when process two wants to start Well, we would pick the shortest remaining time first So p1 still has five time units left to execute because it takes seven and it already executed for two So it has five left and then process two has four time units Remaining so we would context switch out p1 and start executing p2 So p2 would execute for two time units until process three comes in So process two now has two time units remaining and process three only takes one time unit to execute So the process with the shortest remaining time is now p3 so we would just execute p3 immediately and then switch back and Also p4 would come in at the same time which now has four time units remaining So we would pick the shortest remaining time first. So p2 only has two time units left So we would just finish it up quickly and then at t equals seven We would have the next shortest remaining time first which is p4 that takes four time units So we'd run that and that t equals 11. We would schedule. We would just finish up p1 So now our average waiting time we have to do a bit more math so we can either So the average wait or sorry the wait time for process one is essentially this whole middle section So it started here and before it finished here at t equals 16 It had to wait one two three four five six seven eight nine So it had to wait nine time units or if you don't want to count the squares So it finished at t equals 16 and started wanted to start at t equals zero. So you just take that difference and subtract How long it takes to execute so 16 minus seven is nine. So it waited around for nine time units P2 only waited around for one time unit Because we started executing it immediately and then it waited around for one time unit while p3 was executing and then it finished up and Then p3 waited for zero time units as soon as it came in we scheduled it immediately because it was very very quick and Then process for waited for Waited for two time units. So it came in at t equals five and started executing at t equals seven So our average waiting time in this case is three. So Any questions about that? Little bit trickier because there was a little gaps, right? Okay, so this is as hard as we'll get today round robin, which is kind of what you did in lab two. Yeah So the question was why does p2 wait for P4 wait for to see you. Yeah, so it waited for two, right? so p3 came in at t equals four and At this time we had p1 and p2 that had some time left so P1 came in here and had seven time units and then executed for two So it still has five time units left. It needs to execute Then p2 came in it had four time units. It needs to execute, which is shorter than five So we scheduled it So it ran for two time units So now it has two time units left and then when p3 came in it only needs one time unit to run Which is shorter than all of them. So it just schedules it immediately So as soon as it so it prioritized the shortest job or the shortest remaining time so the short tasks we just switch to it we get done out of the way and Reduce our average waiting time So like before here our average waiting time since we can preempt stuff was three in this case It was four All right, so so far The scheduling has been one not super realistic because we won't know how long stuff takes and then two It isn't super fair. It has that starvation issue where long running processes may never execute So if you want to handle fairness one thing you can do is just round robin So you give every you essentially divide the execution up into time slices Which are called quanta don't ask me why computer scientists want to use fancier words and just time slice Who knows they're weird people So an individual type time slice is called a quantum again I don't know why they want to make things difficult But all you do is maintain a FIFO queue similar to first come first serve and You just circle back in the queue again and again and again and just serve them in order But instead of running everything into completion You just give everything a time slice and try to be fair by just divvying it up between all the different processes so Given your time slice you just give a process of a time slice let it execute for that time slice If it finishes great if it doesn't finish you just add it re-add it to the end of the queue when it's done And this is the first scheduling algorithm that's actually used in the Linux kernel So this is like this simplest scheduler you can use and it is a perfectly valid one If you had to implement your own schedule for your own, I Guess threading library you pretty much already did this right? So this is where that comes from so what are some practical considerations for determining the quantum length? They're like the length of the time slice Yeah Yeah, so there's some penalty for context switching which is some overhead But the quicker or the shorter the timeline length the better my response time is going to be right and then What happens if my quantum length is essentially infinite? well that becomes You then essentially becomes exactly first come first serve right which is pretty which is pretty terrible So this and Yeah, so you're if you have the quantum length really really low You'll have a lot of context switches. You'll have good response time But you'll have a lot of context switches and if it's too large Then you're essentially going to have first come first serve which is kind of a crappy scheduling algorithm So Let's go through this And do round robin with a quantum length of three time units so again, I have the I have the arrival times at the top and I'll just write it out just to make it easier. So let's do Round robin With the quantum length equal to this three so My time slice whenever I schedule a process to run it will run for at most three time units Before I take away and a context switch it out So at t equals zero so right here whoops So right here at t equals zero my q is Just going to be p1 because it arrives at that time. So if I need to pick a Process to run I have no other choice, but to pick p1 So I would pick p1 to run for Three time units so at the bottom at each one of these I'll write out the q at the bottom so At t equals two my q would have been empty and P2 came in so it just goes to the front of the q Then at t3 whenever p1's time unit is done It would get re-added to the back of the q so now my q would look like p2 then p1 So when I picked the next OBS crash All right, so we are Back no, they're still recording. I resumed it. It's saved Okay So at t equals three here in our q there's p2 p1 So we would pick p2 to execute for its three time units because it takes four time units to execute And then while that's going on Right after we schedule it. We would take it off the q so p1 is next in Our q and then at t equals four p3 comes in so it would go to the back of the q So our q would be p1 then p3 Then t equals five p4 comes in so it would be added to the back of the q so it equals five That's what our q looks like and then at t equals six whenever Process two is done. It's done. It's time slice. It would be added to the back of the q So it would our q would look like this so it'd be p1 p3 p4 p2 so We pick off whatever is at the front of the q so it's p1 which executes for another three time units which brings us to t equals nine So our q at that point would be p3 p4 p2 and P1 still not done executing so it would just add itself to the back of the q So p1's at the back of the q now P3 is the next one to run it only lasts for one time unit So it would just be scheduled One run for its one time unit and be done Now our q just has p4 p2 p1 So we would execute p4 because it's at the front So it would execute for its three time units now. We have p2 p1 p4 in our q So we would execute p1. They're sorry p2 which just has one time unit left. It's done So now we just have p1 p4 in our q we execute p1 and P4 is the only thing left in our q we execute that and then all our processes are done So any questions about that? Yeah, you you're told that So it's like what's the scheduling if the quantum length is three? Yeah this is Depends on the processes So if we want to make you waste time we could say hey try all the do up do this for all the quantum Lengths and tell me what the best ones are for this process That that would kind of be mean though Hopefully that doesn't actually happen but usually Reader things have happened But so if we want to calculate, you know weighting time So usually there's three metrics you want to calculate when you do this so it's average waiting time So our average waiting time here would be for p1. So how long did p1 wait? Well, if we count so it started here So p1 started executing there and didn't finish until here T equals 15 Right, so p1 it waited around for was that 15 minus 7 so it waited around for eight time units, right? Yeah, so p1 waited around for eight time units P2 how long did it wait around? Well, it started here at time two it didn't finish until P equals 14 So 14 minus 2 it's 12 and it took four time units. So it also waited around for eight We could also just count the number of time units it waited around for when it started So if we count So it started exit or we wanted to execute at t equals two So it waited here at that yellow mark. So one two three four five six seven eight So it waited eight time units until it actually executed, right? So P3 How long did it wait? Well, it waited around for hopefully five so it started at t equals four So it waited here one two three four five So P3 waited for five time units and Then finally for P4 how many time units did it wait? Well, it waited for one two three four five Six seven so it waited for seven time units So if we do that for our average waiting time our average waiting time Divide by four would be like seven So next thing we would do is average Response time So for P1 so response time is just whenever it arrives And then how long it took to start executing so this is less we have to count So for P1 it waited around for zero seconds until it first started executing. So it's a zero P2 how long did it wait for well it arrived at T equals two and started executing at T equals three So it only waited around for one time unit P3 Well, it's waiting time is the same as its response time. So it waited around for five time units Again, so it arrived at T equals four and didn't start executing T equals nine and then finally for P4 It arrived at T equals five and didn't start executing until T equals ten So it also waited around for five time units. So if we add all those together, it's eleven divided by four which equals like two point seven five and Then the other metric we might want to keep track of is the number of context switches So that's only when we change between processes. So if we count the number of context switches, there's going to be one here Between process one and two. So one two three four five six seven So there are seven context switches All good everything makes sense cool, so Let's do it again as hard as it's going to get. So here's your question. What happens when you change the quantum length? So given all of our metrics, let's do it with the quantum length equal to one So this is just going to be the exact same process, but just a lot more writing. So let's do it again because that was so fun So T equals zero There's only one process. It would just go to the front of the queue. So it would execute Then at T equals one it just gets shoved to the back of the queue. So there's only one process again So it would execute again for its one time unit Now at T equals two process two comes in so it would go to the front of the queue and this is like kind of a tie where A new process is coming in as you're re queuing yourself So in this case you would prioritize the newer process just to get its response time down So at this case at T equals two P2 arrives and then P1 Reads itself to the back of the queue. So our queue would look like this It would be P1 or sorry P2 followed by P1. So we would schedule in process two Then our queue would P1 would be in our queue and we would read P2 to the back of the queue after it's done It's one time unit. So Then process one would execute for its one time unit And then here our queue would have process two at the front then process three comes in So we would add it next and then re queue process one at the end So it's everyone on the same page for that one. So this is as far as it's going to get today So we can breathe a sigh of relief So that's our tie we pick the process that is at the front So process two would execute now our queue has process three process one Now we're also Re-adding process two to the back of the queue while process four arrives So we'll prioritize the new process and then our queue looks like this So everyone good with that Now P3 is going to execute for its one time unit. It only takes one time unit to It's like total running time is only one time unit. So it's done now So thank Jebus we don't have to worry about that in our queue So now our queue is one shorter. So now we guess Essentially, this is where the round robin is we're just going to go around and around and around until everything's done in the same order So P1 executes and we have P4 P2 P1 in our queue So P4 executes. We have P2 P1 P4 So it's going to go to Right and at this point, we always know it's going to go one four two one four two one four two into they're done so one four two Four so at this point after this one four two Process two is now done so our queue would just look like process one then process four because Process two is executed total. It's four time units. So it's done now So now we just are round robbing between process one and process four. So it would be one Four and at this point four still has one time unit remaining. It's not done yet and then one Four and now they're both done All right So everyone agree with that All right, so now we can do our average waiting time So what's our waiting time for P1? Yeah Yeah, average waiting time for P1 is eight. So it finished here at T equals 15 start at T equals zero and It took seven time units. So and it and of course if you just count the number of time It is just waiting around. It's one two three four five six seven Whoops. I highlighted one One two three four five six seven Seven eight. All right How long did process two wait? I think I heard a six. How long did process three wait? One that was easy All right process four. I heard it's seven So if I do that Divide by four 5.5 cool So next average Response time So what's our average response time now? So how long did P1 wait till it started executing? Big ol Big ol zero Process two Also zero it arrived at T equals two it started executing immediately. So that's cool What about process three One so it arrived at T equals four executed at T equals five so it waited around for one What about process four two so by doing that and Calculating that it appears that our response time We lowered the quanta and our response time got way better from before, right? So now our average response time is zero point seven five while before it was two point seven five So our response time is way better now our average waiting time went from seven to five point five So that also improved but doesn't necessarily improve and then finally we need to count the number of context switches which if we were correct before in our argument there should be a lot more context switches and There should be because I had to write a lot more so That's what one context switch one two three four five six seven eight nine ten eleven twelve thirteen fourteen So oops So our response time and average waiting time both went down But our number of context switches went way up So this is when we do this we assume our context switches are free which we know they aren't Yeah Yep Yep, so p2 runs for two time units in a row there just because there's no other choice So yeah, so you would care about when begins if it's like an interactive application So like if I click a mouse when do I see some response? So you don't really care when Firefox ends you care when you see your mouse movement or something like that And it's probably more realistic than average waiting time unless it's like you're just doing pure computation so This crux of like doing pure computation versus user interaction is kind of what we'll see and more advanced scheduling Alright, so let's do it again So quantum length of ten Well, this case should be a lot simpler. So if we have quantum length of ten, it's essentially first come first serve so first and it's essentially first come first served without Preemptions because they'll just execute until it's done So this will look exactly like the first example of the day where we have p1 It comes in because it's the only choice at t equals zero then after that It's just the processes in order because it's first come first serve So p2 would execute and then p3 would execute and then p4 would execute So if we do that Compute all these metrics again There's only three contexts, which is now which is a slight improvement But our and our average waiting time actually went down slightly But our response time shot way up. So it was like 2.75 for quantum length of three and then 0.75 when the quantum length was one and now it's 4.75 So this was the same case as first come first serve without preemptions So the round robin performance depends on the quantum quantum length and the job length So people have simulated this before so even with round robin. It's a bit difficult to argue about in general There's no perfect answer So round robin has like a fairly good low response and good interactivity It has fair allocation of the CPU and a low ish Average waiting time when the job lengths vary which is just found through simulation but The performance does depend on the quantum length So too high it becomes first come first serve and then too low There is way too many contexts which is which is just a lot of overhead So you probably typically on a real system you want the overhead to be like in the single digit or less percentage And then just a fun thing you find from simulations is round robin has a Really poor average waiting time when the jobs have similar length and that's again just found through simulation So scheduling does involve a bunch of trade-offs today hasn't is like the basic scheduling We'll get into fun stuff next lecture. I guess it's tomorrow, but we looked at a few So there's first come first serve most basic stand-in line at the food truck Shortest job first. So that's a tweak to provably reduce the average waiting time and Then if you allow processes to be preempted you could tweak it so that you have shortest remaining time first and That will again optimize the lowest Or waiting time and you also might see it called a turnaround time So total time from when it starts to when it finishes and then we saw round robin which Tries to optimize fairness and response time. So that's it. Just remember I'm pulling for you