 All right everybody, let's get started today. How is everybody today good? Good should we do a big good morning ready one two three good morning? All right Everybody's awake. This guy's excited Did you didn't do that did you? Probably not okay. Let's just hope let's hope not There seems to be other spots around here. So okay good. All right Okay, so today we're going to continue our Discussion of the virtual memory system on Monday. We got through Paging we got into paging right so so we essentially motivated The idea of paging by looking at the problems with both base and bounds which is really terrible and segmentation Which is better and which we borrowed a lot of ideas from but still has some issues right and so today We're going to continue on talking a little bit about now that we have these pages right which which we like There's things about pages that we like it's nice fixed size No external fragmentation or small enough to limit internal fragmentation We can use the hardware to help us make it fast, but what happens in the operating system itself, right? So once entries are in the TLB, that's great We're all set right, but how do entries get to the TLB and how do we make sure that we can locate? Information about pages on the system quickly when it's needed, right? And then finally we're going to talk a little bit today about what happens when we run out of memory, right? So you guys I think I think you guys know what happens, but we'll talk specifically about about sort of how we can Use a backing store right a slower larger device in order to allow Processes to allocate more memory than is actually present on the system right and we'll talk about what happens How we get that to work and then what happens in cases where we need to either move pages out of memory? Or bring them back in right and then finally if we have time we'll finish up with just a little note about hardware and software managed TLB alright So there seems to be something wrong with the partner selection form a couple you guys emailed us at this some point this morning I'll look at it and fix it. It's probably just something broken on the website and So how many people looked at assignment 2 right? So everything is out there. How many people looked at assignment 2 yesterday? Okay Some people didn't some people didn't raise their hands when I asked them if they looked at the assignment But they raise their hands if they asked them if I looked at the assignment yesterday, right? So hopefully the second group is a subset of the first group or whatever so So I thought a lot about exactly how did you know how to work in the design aspect in this class So when I when this class was taught and I was a part of it typically we would really stress the design aspect Right, we would have each group work to produce a design for about a week And then we would have that group meet with the core staff to discuss the design in detail, right? We just don't have enough TAs to do that right and so I was trying to think you know I didn't want you guys I want you guys to get some early feedback from us because that's a really important part of doing well on Assignment 2 and assignment 3 right again these assignments are really under specified So a lot of what you guys have to do for this assignment is first of all figure out what you need to do Right, and then second of all come up with a plan for how to do it I had a plan that involves your partner a plan that involves meeting the objectives and testing and sort of some reasonable Plan and there's things that you're going to have to design yourself, right? So we're not going to give you the data structures necessary to store page state We're not going to give you the data structures necessary to store information about file handles for example So those are parts of the system that you'll just have to come up with and design yourself, right? So what I came up with was this this compromise and hopefully it's not a terrible compromise But what we're asking you guys to do is to put together a two-page I'm calling this the executive summary of your design document, right? So your design document in theory to be good would actually be longer than two pages, right? And it would be more specific But the executive summary is covered in the assignment and what I want the executive summary to do is I want it to do two things first of all I want you to use it to demonstrate to us that you understand the assignment, right? That you understand what you have to do, right? So if we read your assignment to executive summary and we say well geez like this person There's no process support here at all Like we may point out that there are certain system calls that you will be unable to implement properly without adding some things, right? So we really want to see that you guys have thought through and figured out all the different things that have to be done, right? And the second part of course is that we want to have some idea that you guys have come up with reasonable ways of doing this, right? So we want some, you know, high-level Description in readable plain English about how you plan on handling some of these things How are you going to allocate process IDs, right? How are you going to store information about page tables, right? How are you going to get weight and exit to work properly, right? So things like this So look at the assignment This is the goal, right? And the reason it's two pages is partly to kind of force you guys to be concise and precise about what you're doing But also clearly because, you know, we have a limited number of TAs and all, you know, four of us are going to have to read, you know 10 or 15 of these each or something like that, right? So we're trying to keep our workload manageable, right? But the goal is you get these in before spring break and while the course staff will have time to look at them So we can give you some feedback and hopefully by the time you guys really get into the implementation You'll have some feedback from the staff about, no, no, that's not a good idea, you know Or or yeah, that's a great way to do this, right? And so that hopefully it'll build some confidence in helping you guys tackle the assignment, all right? Any questions about the design portion of this, right? This is an experiment. We'll see how it works, right? I hope that two pages is long enough to give you enough time to summarize the key points in the design I think it is, okay, and Actually, maybe it could even be like one page, right? But the point is on some level the shorter the better But please make sure that you accomplish those two objectives, right? You tell us, you demonstrate that you understand the assignment and you propose some reasonable plan of action and some reasonable solutions to the problems that are inherent in getting system calls on OS 161 to work, okay? Any questions about this? All right, great. So Questions on material on Monday, so Monday we talked about segmentation We went back through segmentation and then we got into page translation, right? Just just really just got through page translation So any questions about about this material before we do a little bit of review? Any questions? All right, so given that there are no questions everybody understands this stuff perfectly, right? So how does segmentation work? I'll start in the back of the room right back here Segmentation, how does it work? What do I need? So what do it's okay, so I have segments that's good. What defines a segment? What are that? There's three pieces of information that define a second. All right, give me one of them. I want to help her out Any contributions from back? Okay, there's a base this base of a base what? Memory what kind of memory? Remember we want to be specific right we have to we have really two kinds of memory now We have what kind of memory and what kind of memory? Virtual addresses right which act like memory and then we have Physical memory that is memory and you have a base. This is kind of a short question You have a base physical address and a starting Virtual address right so I really have a base virtual address and a base physical address, right? That's what that's what defines how I do the translation right and someone also said I have a third piece of information Bound right size of the segment right so I need to know where is the segment in virtual address space? Where is the segment map to in physical memory and how large is the segment right with those three pieces of information? I can perform a both a check to make sure the address is valid and a translation So how do I do the check Karen? Well, okay, so so I'm sorry. I have three pieces of information. I'm giving you a virtual address to translate you're close Right, so the virtual address I give you has to be What? Inside some segment right so there has to exist a segment for this process remember I'm always translating virtual address in the context of a process right there has to be a segment that contains this virtual address meaning that the virtual address has to be in some segment or Meaning that it has to be between the start and the start plus the base of some segment right? That's how I check an address. Okay, how do I translate an address Keith? Yeah, okay virtual if I'm giving you a virtual address and let's say it's okay So I found a segment that it's in what a how do I translate it? Right Well, I okay, so you got the first part right so I subtract the start virtual address and then what do I do? I want to help them out There's there's one more part here Added to the base physical address right so I need to figure out the offset Inside the segment so I subtract the start virtual address and I add the base physical address right that that's how I do this Okay, so I take the virtual address subtract out the segment start add it to the segment base Okay, question is about segmentation and segment translation, right? All right a couple of review questions from last time What's a common operating system trick to make something slow look faster? Caching and what is what is caching specific? Yeah, you know you you you you you you gave the answer now you have to tell me what it means So I have a big slow thing and to make it fast. I put a Smaller fast thing in front of it. Why is the thing I put in front of it usually smaller? Because if it was big I would just use it as the big thing right if I have a big fast thing Don't bother with the you know big slow thing right just use the big fast So right yeah at some level is if you if you think the thing about it, right? The the things on the system that are the fastest to access are the ones that you have the fewest of in general Right, what's the fastest thing on the system to access anybody? Registers registers blazingly fast right on the processor next fastest thing maybe Cash what cash? L1 cash right small per processor cash. What's the second fastest thing? Maybe L2 cash. What's next? Maybe there's an L3 cash. Let's say there's an L3 cash. What's next? Main memory right what's after main memory? Disks and I you know maybe next time we'll put up a graph of this because like you can grab these on a logarithmic access Right and essentially as all of these get bigger and bigger like I mean Your system might have 32 registers or something like that right and you have 320 gigabytes of disk, right? Yeah, so Anybody know this solid-state disks price per byte Compared with physical compared with spinning discs Very still very expensive right so if you have a high-end machine Then you might have an SSD, but it's typically slower right big SSDs are Killer expensive. They're just really terrible. I'm trying to remember I mean when I was building my sheen my machine has an SSD in it, but it's like a 256 gigabyte SSD or something When you get up to a gigabyte or no when you get it well you get up to like half gig and higher They just get really really terrible, right? But it's coming right and and we'll talk more about this make it to storage okay cash Right and at some level one way of thinking about operating systems overall is just a series of caches, right? Registers are cash for L1 L1 is cash for L2 L2 is cash for memory memory is cash for the disk This is cash, maybe for the network or maybe memories cash for the network It's all a bunch of things with different properties that that we're trying to get to work together to seem like They're all as fast all as fast as the registers maybe like I have as much space as the entire Internet But it's as fast as my registers right that would be like that'd be the dream machine, right? okay Now in this particular context, how do we apply this this classic technique? We throw a cash in front of something so first of all back here Carl. What's too slow? What are the thing that what's the thing we're trying to make faster in this case? Well, actually okay access to memory is part of it, but but but it's actually right up on the slide What's the thing that we're trying to make faster? address translation, right? I'm getting I'm only letting processes use these virtual addresses now So I've got to translate all of them and if I do it in the kernel, it's way too slow, right? And the what specific piece of hardware do I use to make this faster? anybody TLB right I used a translation look-aside buffer to cash the Translations so that the kernel doesn't have to constantly look them up, right? If the kernel had to constantly look them up way too slow, right? Classic technique slow thing is the kernel Fasting TLB, right? Where do entries in the TLB come from though? Who who puts them there? the operating system right and specifically the kernel partly because We have to have privilege in order to multiplexing, right? This is this is how I divide and enforce memory divisions right is by managing entries in the TLB, right? We'll talk later in class again toward the very end about cases in which the hardware can actually put entries into the TLB, right? But the operating system is always in charge of what those entries are, right? The hardware might be able to find them, but the operating system is always in charge of establishing, right? That's how we multiplex memory That's the privilege that the operating system has that allows it to divide up and enforce these divisions, right? All right Pages right so we came with this great idea pages pages are neat, right? And what are pages like right? How can you think of pages pages are like what segments? Fixed size segments right every page. It's like a little segment. It has to start Virtual address if it's in memory and has to start physical address But the bound is always the same so we typically just ignore the bound and we say you know the pages are 4k And then we don't have to think about the bound, right? All virtual objects on the same paint map on the same virtual page map to the same physical page, right? This is like having a again having to fix size segment all the addresses in that segment map into the memory That's reserved for that segment, right? All right, the portion of the virtual address so again now now that I have virtual addresses with fixed size pages, right? I can talk about a portion of the address that refers to the virtual page and the portion that refers to Something else, right? So what do I call the part that refers to the page? Anybody remember John? Don't remember Go down the row No idea, but just for a virtual page number, right? It's named after the virtual page. There's only one thing to remember here. What do I call the rest of the virtual address? The offset, right? It's the offset into that virtual page, right? Okay, now let's talk about how do I do translation, right? Got page translation. I have a virtual address So what's the first thing I need to do? How do I check that the address is valid? Anybody Well, let's say I'm let's say I'm loading an entry into the TLB the TLB said hey I don't know anything about this page the kernel is just trying to check to make sure the address is valid, right? What's that? Why need to split it first like the splitting it allows me to identify what? Well, maybe the first 20 bits depending on but in general I split it into what? The virtual page number and the offset, right? So I take the virtual page number and now what what do I have to what what does there have to be in order for the address to be valid? There has to be a translation defined for this virtual page number, right? This virtual page number has to be a virtual page that the operating system has decided to let the process use, okay? So in the case of 4k pages exactly what I do 32-bit address split 2012 20 is the virtual page number 12 is the offset, right? And I check to see if there was a virtual page translation defined for this virtual page number, right? Now, how do I translate it? Let's say I find a virtual page a physical page translation for this virtual page. How do I translate this virtual address? Pick down to you guys enough over here right there How do I translate this virtual address? He doesn't know let's go back to the corner Anybody over in this corner want to Well, remember I'm not I'm not the TLB has asked me for help, right? So the TLB doesn't know anything about this, right? I'm the kernel I'm trying to figure out how to translate, right? Exactly, right? I take the physical page and I add the offset back on, right? And if I'm doing this with 4k pages or another page where there's a nice split I can just see ink the address apart plop it right back together, right? All right Let's talk about page size, right? So what what happens if pages get too small, right? Remember we chose this page size and it was kind of a compromise between a couple of things So what happens if my pages get really really small? So the TLB isn't going to be able to very map very much memory right because the TLB is fixed size So that's one problem. What's the other problem? Too much kernel memory devoted to what? All the information I need for the translations right twice as many pages means twice as many Translate and we'll talk today about the state that the kernel is going to keep around, right? But the data structures today are designed to grow in a reasonable fashion But they will grow as the number of virtual pages, right? So I can't map it off memory in the TLB and I have too much kernel memory devoted to data structures, right? What happens if the pages get too big? Huge pages sounds like a great idea, you know, I can map lots of memory, you know the kernel data structures get really small What's the problem? Internal fragmentation, I you know a process needs 32 bytes and I give it a 2 gigabyte page, right? You know it might as well just give it its whole yeah, we might as well go back to base and bounds at that point, right? That would almost be better, okay All right, any questions about this now that we've gone through this yeah Yeah, sure So so one of one of the things that is frequently done, right? Is that you can imagine that I can I can define something in the kernel that almost looks like a segment, right? That has a start address and an end address. That's a multiple of the page size, right? And then essentially I can figure out so there's two things I have to check right one is that the address is valid, right? The kernels that the process is allowed to use it And so I can use that segment like thing to check if the address is valid, right without having to look through all the page structures, right? Then but the next thing is then what I might be doing is I might have swapped out parts of that segment, right? So on some level I do need some per page information somewhere, right? Because what I might have done is I might have taken half the pages in the heap and Hid them somewhere where the process can't find them, right? And so when the process asks for that page again after you know a couple of hours I need to be like okay where to go, right? So I do need to keep some page information, but you're right There is a way to combine some ideas from segmentation in order to do the the validation check, right? With the idea of paging which allows me to move things around in a page granular. Yeah, it's a good great question any other questions about Sorry So so there's usually one TLB per processor, right? That that is in charge of translating the instructions are executed by that process, right? And if you look on your kernel what you'll see is that there's actually so so if I invalidate what problems does this cause, right? Let's say I have a process running and for whatever reason I'm going to invalidate an entry in the TLB And we'll talk later about why I might do that, right? But what on a multi processor machine or a multi core machine with multiple TLBs? What problem does this create? Right because I have four TLBs So the mapping might be loaded in every TLB and if I really want the process to stop doing it What do I need to do? I need to well essentially I need to find a way to yank it out of every TLB, right? And if you look in your OS 161 code, this is referred to as TLB shoot down, right? What it means is that I'm one core is trying to you know potentially evict a page from memory and invalidate the TLB entry, right? And on some level has to communicate with all the other processors to make sure that that translation is is evicted from the TLB if necessary, right? And what is actually used to do this at least on our system or inter processor interrupts, right? So there's a way for us to to use the process the interrupt mechanism to send another processor in an interrupt Which causes it to enter the exception handling code and the kernel gets controlled, right? And we can use this to implement TLB shoot down, right? Good question. Any other questions? Awesome All right, so let's talk about how we store this information, right? So we talked just previewed on Monday the two requirements for kernel So the kernel virtual memory system, right? And this is essentially what you guys are gonna have to do for assignment 3, right? This is almost a perfect description of what assignment 3 encapsulates, right? Yeah, yeah Well, it's the same mechanism used to do a system call, but it doesn't translate to a system call So so what will happen, right? Is that the processor that is trying that that is kind of leading the shoot down? We'll we'll send an inter processor interrupt to the other. Let's say I have two cores, right? I'm trying to get rid of the page, right? So I'm trying to invalidate all the TLB entries, right? You're running along happily doing something else, right? What I do is I send you an inter processor interrupt That's the same. It's it's it's more accurate to think about it like a hardware interrupt, right? The other processor will trap into the exception handling code and be like what just happened Like clearly there's something that just happened that eats my attention and they'll realize that it's me, right? And I'm over here telling you if there's an entry in your TLB for this page Please flush it because I'm clearing that page out. Oh, yeah Yeah, absolutely, right and and it leverages this this inter processor interrupt mechanism, right? Which is necessary to do this. It's expensive, right? This essentially means that well, you know I have to every core has to trap into the kernel and look for this, right? So this is kind of ugly, right? But you know again, it's one of those things that just you just have to do to ensure consistency. All right Okay, so two requirements for for page state one is I need to store the state Compactly if if hopefully right because again the amount of memory The kernel has to use for these data structures grows as a number of virtual pages So if I can slam it into a small data structures, I'm doing well The second requirement is when the TLB Ask the kernel for a map that says the process tried to use this virtual address I have no idea what to do the kernel has to locate that address rapidly, right? Because the faster I can do this the faster I can get that instruction restarted and the process goes on Okay, so so what information let's talk about some of the state that we need to store right about each virtual page What's what's what's the most fundamental piece of state? Let's say the page is in memory, right? What's the most fundamental piece of state I need to keep around? That's a good ring tone. Yeah, what's that? Okay, well, I wouldn't call that the most fundamental state. That's that's that's good That's something we need that I hear it from a period That's another piece of state. I need but the most fundamental information. What am I trying to do? The physical address, right? I said it was in memory, right? But on some level the location Where is the data that was on this page, right? Now it hope it might be a memory. We'll talk today about where else it might go, right? But when a process tries to use a virtual address The kernel has to figure out what the heck did I do with this data? You know like it wrote some it wrote some data onto this page a while ago And now it's using the page again. What the heck did I do with that date? All right, so that's the first thing okay could be a memory could be on disk It also might be a new page that the process has never used before a page That's valid that a page that's allowed to use but you know if I allocate some heap the first right into that heap will cause The kernel to have to locate some information and and what what will I do in that case? What what what do I return it, right? It's asking to write into this page that it's allowed to write to But that it's ever used before what what should I return to it? What what will that page be full of? Nothing zeros right, so I need to return it a blank page. We'll talk about this on Monday Right Monday, we're going to go through a whole long overthought example about exactly how all this stuff fits together So I think it's important to see all right So permissions right another piece of page state that you guys hadn't thought of right? Again, I like these virtual address abstractions that allows me to aside permissions to virtual addresses But if I'm going to do that the kernel better remember what they are right? So if I allocated this pages read only I need to know that right because if the process tries to do a right I need to stop it, okay, and Then we talked a little bit somebody mentioned Robert mentioned Has this page been used recently so in order to do page replacement and to figure out once I run out of memory And I have to start actually moving things around and maybe moving pages out of memory It's very very helpful to have some statistics on the usage of those pages, right? This is not always easy to capture But usually page table Entries will have some of this right and and again, what's the requirement here? What what are we after? We want to store this information How it would be great if this if I could sort this information in a very very what? Anybody That's that Compact right I want this to be compact because the number of PTE the number of well I shouldn't have said PTE's here. Okay, the number the amount of state that I have grows as what? What's that Well the number of page table entries, but how many page table entries will I have on a system? roughly I Need one entry for for each what? No virtual page Right every ever and that's worse than the amount of memory right that could potentially be much much larger than the amount of Memory I have because processes might have allocated a lot to virtual address base that they're not using but for every page in the virtual Address space I need this state right so the total number of virtual page is allocated by all the processes running on the system Okay, so we refer to this as a page table entry a page table entry Stores and I've got a little bit ahead of myself here We'll all explain the page table part in a minute right but a page table entry Stores information about a single virtual page used by a single process on the system right and sometimes we refer to these as PTE's and Normally we can actually Cleverly jam all this stuff into one 32-bit machine word right which is great right because it means four bytes for page table entry That's usually about the best we can do right So let's go back and let's say that we have 4k pages. How many bits do I need to represent? the physical The location potentially the virtual page number the location on disk how many bits do I need to do that? 20 right and then you know I might need four bits for permissions because I've got three different permissions I might need one bit to determine whether or not the page is in memory or not And then I might need you know like one bit to figure out has the page been read or Written to reason and you'll see that I still have some space left This is only 26 bits right so I have six bits left over that you can do anything you want to right and and I don't know People find things to do with this right, but anyway This is one of those cases where I do some try to do some clever tricks to sort of make this as compact as possible Mainly sort of using some bit masking. Yeah, so so right. That's a great question Per you you can think you can potentially think of permissions as being a per-segment thing right? So this goes back to John's comment I can store some of this information potentially in a segment data structure right that I Also have to access right but on some level every page has a permission right if I assign permissions per segment I can store them in some sort of segment data structure right, but I still need to know for a particular page What are the permissions right, but you're right? I might be able to yank this out of here right save four bits Yeah, Robert for caching. What would I cash in there? So so that the remaining six bits I mean the problem of the main six bits right is that they're sprinkled all over the place right? They're interleaved between all the other bits potentially My guess is that most systems find a way to put those to work right they might do something where instead of just storing a reference bit They actually have some counter that they use that that is increment them in the pages axis I don't know right we might be interested in a look at Linux and see what Linux stores You could yeah, actually you could do that right if you had a TLB that had I don't know What's two to the sixth whatever you know that many slots right you might be able to figure out which slot it was in Oh, yeah, yeah, yeah, okay great. Yeah great idea So if I if I need to figure out which cores have loaded this translation, that's a great idea I could I could use some bits for that right so I could have one bit per core and I could set that bit by four cores I can figure out okay this translation is loaded in these two cores And so when I'm doing shoot down I need to I need to talk to those cores to make sure they yank it right Okay, great idea all right, so So the other thing I need to do I mean this you know this you guys are gonna get you guys are gonna get to Do this for assignment three right, so I'm not gonna go over this too much, but this is just this is just you know Bit bit tricks right That the more Interesting part of this is how do I find so now I've got this page table entry four bytes per page for virtual page on the system How do I find this stuff right? So essentially the prompt remember our old example process machines store to address OX 10,000 right and the MMU says I don't know anything about this address. It's not in the T.O.B. I Don't even know if it's valid or not currently got to help me out right and at this point, right? Exception happens the kernel starts running and if we did all around here, right? And and we take all this time looking around right if it then then the look that the worst thing that the thing That we didn't want to happen already happened the entry wasn't in the cache Right, so now that I have a cache miss. I need to make sure that that path is as fast as possible, right? So so again, I think I've just given it away, but what are the requirements for how we locate page information? There's actually two complementary requirements here one of them. I've just hinted at what is that one require Speed be fast, right? I mean this is this is what people sometimes call. Oh, ah, no gave them both away at once Okay, this is what sometimes people really was a hot path, right? This gets this path gets executed a lot and If you could trim off a couple cycles from it, you can improve this just performs to the system quite significantly Alright, and what's the other one? Maybe if anyone you saw the flash in on the screen. What's that? Compactness, right? Why right? Why do I care about compact? Okay? You you you saw it and now you have to explain it to me, right? I've got I've got this I need to store all this page information I want to be able to locate things quickly, but but what's the other problem here, right? I mean all these data structures are going to do what? What do I have to what do I what does the curl have to have in order to store these? They're gonna take up space, right? So if I if I have too much space to make this fast Then it's then essentially I'm reducing the amount of memory the process is actually can use right? So there's some balance here between the speed of translation and the compactness of the data structures, right? So so let's let's explore this right so we call this structure a page table Right a page table is some data structure that the kernel uses to rapidly locate information about a page on the system So I give you a virtual address and a process ID and you are gonna return me some information about that page where it is The permissions on it, you know some information about the statistics, whatever, right? Why is this done per process? Why couldn't I have a global one for the entire system? Every process is a separate page table. Why? What's that? Every process has the same view of memory and The virtual addresses are specific to a process right so again process and virtual address go together They don't make any sense separate, right? All right So so okay, so let's start at one end of this is our usual. This is our usual technique in this class We spend we have some fun beating up a terrible idea and then we move on to something that's a little bit better Right, so let's talk about flat page tables, right? so a flat page table is essentially what it sounds like it's one array and The array is indexed by the virtual page number and the array can either store the page table entries directly Or maybe it has pointers to the page table entries, right? Okay, and you know here's how this would work, right? I have my I have my process address space I have this flat page table. I have page table entries, right floating around in the kernel heap somewhere and Essentially, I just have a one-to-one mapping between virtual addresses and slots in this flat page table, right? I mean it looks the process translates to virtual address It's in its code segment it translates right into the flat page table I use it as an index points to some page table entry, right? Same thing with the heap, right? So what about speed here? Well, what is how fast can I do a translation here? It's a one it's a single look up. Yes. This is awesome, right? Great, it's used all I do is I use the virtual page number directly as an index into my array How large is this array? What's that? I think you're saying it but I think what okay, can you convert it to bytes? And I convert two to the 20th Four megabytes, right? I actually think this is I think I lost a factor of two in there But anyway, this is huge. This is more than I want, okay, and then most of this is unused, right? This has the same problem that I saw before right where I have this address space. That's mostly empty, right? And now I have a flat page table. That's mostly empty, right? Most of these indexes are not used, yeah No, no, no, this is this is a C array, right? I take the virtual page number and that's just so virtual page number zero is the zeroth index in my array, right? It's just a standard C array. I can I can I can allocate an array like this in C and I can index it directly Yeah, I have to allocate right one four megabyte piece of memory That's contiguous or at least looks contiguous, right? So this is kind of terrible, right? And again, this is like we keep coming back to this The sparsity of address spaces is always giving us problems, right? It gave us problems before we talked about how to do translation with segments and pages and now it's giving us problems We're talking about how to do state, right? All right, so let's try a different different approach, right? What about a linked list? Okay, all I do is I keep a list of the all the PTE's maybe I sort them by virtual address But I don't have to right and on every Translation I just searched the list, right? So here's how this would work. I have my page table entries I put them into a list, right and now what happens, right? The process tries to access a virtual address that's in its code segment and I essentially just look Through the linked list until I find the PTE that matches, right? So I'm looking for the page that matches that page. All right So this is another approach speed how many Accesses on in general will it take? Oh of n where n is what? The number of virtual pages right valid virtual pages in the processes address space, but what about compactness? How large is this data structure? You know four bytes times n potentially, right and it's completely used so that's great, right? It's it's this is you know, so this is nice and just want to point out This is a completely especially when your processes have small numbers of pages. This is totally okay, right? So for assignment three we get people that decide that they need to do some sort of really complex Page table like the one I'm about to describe. It's not super complex, but it's not necessarily the right thing Whereas when you have processes that have small number of pages, this works completely fine, right? This is a totally valid approach, right? But let me talk about what a lot of modern systems actually do right because what I'm going to try to do is I'm going to try to be a little bit more clever about how I use my data structure, all right, so I Said to you what I'm going to do is build something looks like a tree, okay, and There's going to be one top-level node and then potentially a bunch of second-level nodes and on some systems They actually have a three-level page table, right? So they're actually three levels of this tree, right? And when I do is that I take my virtual page number, which is 20 bits and I split it into multiple parts And each piece is used as an index in this in a separate level of the tree, right? So with 4k pages this works out kind of nice, right? I split my 20-bit virtual page number into a 10-bit top and a 10-bit bottom The 10-bit top is used as an index into the top level array That's used to locate the second level array And then the bottom 10 bits is used as an index into the second level array And that's used to locate the page table entry, right? One of the nice things about 4k pages is this, right? Maybe this is why they're so popular if I do this every page table has two to the tenth entries It's an array and each entry is four bytes So my page table every every node in my page table is 4k or one page, right? So that's kind of nice, right? Now again, so so I've just walked through an example about do this But let me walk through a visual example, right? So so what happens here? Okay, I'm given I have a every process has to have a first level page table, right? This is 4k if I have 4k pages, right? So when I translate an address I Take the top 10 bits and I use those as an index into my first level page table, okay? What happens next? What is this? What do I do with these? What is this going to point to? It'll point to another page table another 4k array essentially, right? And now what do I do? I take the bottom 10 bits and I use those as an index into my second level page table and That will either be or point to a page table. Alright, so let me go through this again Right, I use 10 bits as an index into the first level table to get to the second level table, right? The first level table contains pointers to second level tables if they exist, right? And the nice thing about this is I only have to allocate second level page tables for portions of the address space that need them, right? Okay, so if my second level page table exists the first level page table has a pointer to it and Then I use the bottom 10 bits of my address as an index into that second level page table And that gets me my page table entry with information about this virtual address. Okay questions about this So so what does this mean, right? I should I think I should have had a slide for this and I don't okay, so So for this process Every process has in order for this to work every process has to have what? What what part of this do I absolutely need? I need I need the root, right? I need my first level table, right? So 4k per process regardless of how many virtual pages it has and that's kind of tough, right? That's a little bit of a high constant factor, right, but okay, right? But then things get better Because let's say and I wish I could remember this right so so it's two to the ten anyway I won't think about but but ideas each second level table covers some fairly big piece of the process's address space and Any areas where the address base is empty? I don't need to allocate a second level table, right? If I had to get if I had a process that was using its entire algea space And I had had to allocate every second level table that would be terrible But most address spaces are sparse right most of the space is empty and in that empty space I don't need second level tables, right? So in the best case, let's say this is a process with one thread It has a stack. It's got some heap allocated. It's got a few code pages At best how many second level page tables will I need? Three right one second level page shibble will cover the entire code area Another second level page shibble cover the entire heap and a third second level page table will cover the entire stack again You know ignore the other stacks now. Let's say this is a single threaded process, right? So that's great, right? And now I've got what how much total memory devoted to translating addresses for this process Anybody simple math How many k? 16k right one first level page table three second level, okay So what about the speed? How many entries does it take to translate to find a pte on this on this approach oh? One essentially it's two lookups right a look up first level page table And then I do a look up into the second level page right it might be like three or four memory access But it's just to two two indices, right? It's a constant number of lookups and that will actually depend on the tree depth So if I was trying to be more clever, and I had a three level page table which these do exist, right? Then I might need to get a third index into a third level table before I can I can actually translate the address What about compactness I didn't really understand how to represent this so I just said it depends on the sparse So but there there is a way you know you could calculate this right But it really depends on the sparse of the address space if the process that the worst case scenarios that the process has one page Allocated that causes in every second level table, but it has all the second level tables allocate, right? That is really really uncommon right processes normally don't do that right when I get a heap for example My heap is is contiguous and it grows contiguously, right? So I don't get like one heat page there and another heat page like you know 30 megabytes later in my virtual address space I just that this does not have process address bases are laid out, right? There's sparse, but but there you know there are little bits of density here So let's talk before we finish today what time is like a five minutes all right? So let's talk about just in general, right? So we've been talking a lot mainly what we've been focused on up till now is address translation address translation How do we translate virtual addresses, right? How do we find out information about the hungry store that information, etc, right? But remember one of the things that we were thinking about doing with this whole virtual address abstraction is We had this grand plan that would actually allow us to provide the illusion that there was more memory on the system than there actually is all right and The way that we do this I'm going to describe right now So what happens if we run out of memory and this can happen, right? I mean this happens all the time, right on some level As soon as the processes on your system allocate enough virtual address space to exhaust all the physical memory You're out of memory, right? And then you have to start playing games to get this to work Well, right and you want to use all the memory on your system in general memory is usually a lot faster than other some of the Other alternatives, so if you can you'd like to allocate all the memory, right? But you know let's say I have a process that you know It's got three code pages and then it starts running and needs a stack page And then it gets one page of heap and maybe it gets two pages of heap right away and now needs to grow the heap Right, so I don't I don't know why I made that animation. It's kind of stupid, right? I mean you guys can imagine how this work, but anyway, that's the end right? That's all that happens this question okay, so So what do I do now right what happens when we run out? So so I've got two options right someone someone give me the the the easiest but potentially less desirable option What's that? What's that? Well, okay, that's that's even worse right yeah You could tell the programmer to do a better job of writing their program. That's probably not gonna work What can I do in the moment? Right I can just fail you know and essentially run out of core I can say well, you know if I'm trying to allocate memory in exec then exec fails And I go back to the original process that was trying to call exec and say sorry your process of transformation has failed Right if I'm calling fork, I might fail fork and go back to the parent and say sorry you can't have any children right now I don't have enough memory You know if I'm trying to allocate more heap through s-break I might tell Malik sorry about that like I don't know what to tell you but I don't you know I just can't help you out right now, right or if the process is trying to use more stack space I don't you know There's not really a great thing to do there other than to just kill it right because essentially it's it's gonna try to execute another Instruction that's gonna push and pop on to the stacks if I fail at that point, you know, there's really there's really no other way out Okay What but what else can I do right what else can I do I can swap? What does that mean? What is what is what is swapping fundamentally me? Right, but essentially what I'm doing is I'm creating more space right and I'm creating more space by exploiting this property of the virtual address that I can move it around Without telling the process about it right I can be sneaky right So because I have this level of indirection right remember how Google Gaga was about this level of indirection I'm starting to feel that way again today right I Have this great great level of indirection that I can use and essentially allows me to play games behind the processes back Right, so without telling the process what's going on I Can I could do things that it doesn't know about it doesn't have to know about and maybe doesn't want to know About you know it's it's like that guy in the matrix right ignorance is bliss Right, so but what are the requirements for doing this? So the process was using some virtual addresses remember and those virtual addresses Observe the memory interface loads and stores work as the process expected. Okay What do I you know, let's say I'm going to play some games, right? The next time the process uses this virtual address what has to happen. It has to work. That's to behave like memory Right, and in fact it doesn't have to just behave like memory has to behave like the same memory that the process was used Right, so whatever games I play when the process tries to access that address again I better be able to put things back together right Now in order to do this While I'm playing my games, what do I have to do to the data that the process was using at that virtual address? I've got to preserve it right because otherwise they were processed to the load and then a bunch of time went by And I played by magic tricks and then it came back Sorry, if it did a store and a bunch of time of mind I played my games and then it did a load the load might return some different number and that promises to be like Well, it's not behaving like memory right, so you have to preserve the contents. Okay, so let me just introduce you to Swapping we'll come back to this on Friday So we call this process Swapping and specifically we call it swapping when when it's Isaac point out we're using the disc, right? The disc is nice Why is the disk nice? What is the disc? What is the disc usually compared to memory? It's huge right potentially massive even now, right? I mean, I don't know how much memory this thing has in it. It's like four gigs or something, right? It's got 250 gigs of Disc right so in order of magnitude or more and more discs than I have memory right, so that's a good thing What's the problem with the disc? Slow slow. It's really slow potentially really slow, okay? So here's another case where we're trying to present this illusion right and the goal of the illusion that we're going to try to create through swapping is Your system has memory that is as large as the size of your disc But as fast as RAM as fast as memory right if we can play our game well We can present that illusion if we don't play our game well Then your system feels like it has as much memory as RAM, but that memory is as slow as disc, right? So this is terrible, right? This this this system would would feel really really unusable, okay? All right, so let's we'll go through this next time. I think there's one more slot I want to do right so the other thing that so what determines this how well this works, right? how well we do between the two extremes right is How we choose pages to move back and forth from swap To memory and in particular how we choose pages to remove from memory because as we'll see on Friday when we bring pages in It's usually because we have to all right when we should when they kick pages out It's usually because we choose to so on Friday We'll go through swapping and we'll talk about how we select pages to move back and forth to swap