I've recently come across this description of a single processor cache saying that it's
"Word addressed (addresses are left shifted by 2 by adding “00” to end of address inside the processor, this implies that it can address 2^32*4 = 16GBytes of memory"
I understand that word addressing means that each consecutive address holds a word of data versus byte addressing which holds a byte of data at each address. I further understand that left shifting address by 2 means multiplying the address by 4 so we are trying to obtain multiples of 4, but doesn't that imply that each address holds a byte of data thus this is not word addressing but in fact byte addressing and the processor has logic in which we only access a word at a time despite what the memory is like?
So far I am confused on whether word addressed just means we have logic in place to access a word at a time or the actual memory is formatted in a way that each address will hold a whole word and not a byte
Related
As far as my understanding goes, the CPU always generates a virtual address that is made-up of 2 parts- the page number and the page offset. The page number is used for indexing the page table (the corresponding mapping gives the starting address of the frame in the RAM). Now, please consider the following questions. Consider that the word size of the machine is 4 bytes, and the page size is equal to the frame size = 4096 bytes.
Supposing that the page number is 4 and the offset is 3. Then Page 4 in the logical memory maps to frame 8 in the virtual memory. This means that the starting address of the frame is 8.
Now, each frame will contain 4096/4= 1024 words. Does the offset imply for a word inside the frame, since the machine will always fetch a word at a time? What I mean is that does it mean the 3rd word in frame 8?
Is the particular word given to the CPU, or the entire frame? If former, then why does everyone talk about transfer in terms of frames and pages rather than words?
Suppose a page fault occurs. What this means is that the particular page in not in memory. Does it mean that the physical address mapped contains some other page? Does the mapping even exist in such a case when the invalid bit is 1.
Can someone clear-up things for me? One moment I seem to get it, and the very next, I get into a maze.
The key point of paging is that it deals with "chunks" of memory.
It is a map, a function, that translates virtual addresses into physical addresses but not on an address-by-address base. Rather, a "chunk" of continuous virtual addresses is translated together into another continuous "chunk" of, now physical, addresses.
You can think of it as a "translation" or "shuffle" of "chunks" of memory.
The correct term for "chunk" is page.
If try to do a sample mapping you can see that each page contains a set of addresses that all have a peculiarity: their lower bits don't change when passing from virtual to physical. The upper bits instead are arbitrary.
This dichotomy of the address value defines the Offset and Page/Frame number.
The offset is the part of the address value that don't undergo any translation.
In a page of 4KiB there are 4096 addresses, each one with its offset, so the offset has size log2(4096) = log2(212) = 12 * log2(2) = 12 bits.
In short the page size determines the offset size.
It is necessary to break the memory into pages and not words or byte, or in another view it is necessary to group the addresses to translate into pages.
Without pages, the metadata used for the translation, in jargon the page tables of various level, would occupy more memory that the one that under translation!
Offsets are relative to their page/frame thanks to the way their are defined: the offset 1024 (in hex 400h) in the frame 8 means the address 8000h + 400h = 8400h; if the page is mapped to the frame 12 the offset 1024 is still 1024 bytes after the beginning of the frame, 0c000h + 400h = 0c400h.
Being an address, an offset usually denotes a byte, event in architecture where bytes are not addressable. However this is not a standard convention, to know if an offset denotes a word or a byte (e.g. if offset 10 of frame 0 is the byte 40 or the byte 10) check the architecture manual. The first sections are usually dedicated to establishing a terminology to use throughout the book.
Paging happens before the CPU accesses the memory, you can think of it as an high level process. The unit that accesses the memory/bus is mostly unaware of it, as such the CPU read the data that the instruction is telling it to read (a word, a byte, and so on).
People talk about moving a page because a page is the smallest unit that can be characterized.
You can mark a page as non present, but not a word. You can make a page read-only but not a word.
If you need to map, say 16 bytes, you still need to map a whole page since 16 bytes are not characterizable. So we might as well read a whole page.
When a page-fault occurs it means that the page accessed is, at any level in the page-tables, non present.
This may mean a wide range of things, from the fact that the Present bit has been simply toggled (with the page still there), to the fact that the page has been saved to disk and zero-ed in memory.
Since the mapping function is total, meaning that every value is a valid value, the CPU need a way to know when a value is not valid.
The Present bit does this: tell the CPU that a translation must not be performed and that an exception must be raised instead.
The OS use this exception to be notified of when a page is needed, it doesn't need to reassign the mapping to another page or zero the memory.
When people say that a page is removed they mean that it is removed from the mapping, all modern OSes also zero-d the page to prevent leaking of information to other processes though.
So if a physical frame is not mapped it doesn't mean that another page in another process is mapping it, it simply mean that that range of addresses cannot be accessed.
As said above there are a lot of reasons for an OS to do this, including protection.
You have things a bit backwards. The operating system defines a logical address space for each process. The logic address space is divided into units of memory called PAGES.
The operating system logically maps the pages of the address to either physical page frames or secondary storage If the operating system maps pages to secondary storage then is using virtual memory.
In ye olde days all systems that did logical memory translation always did virtual memory mappings to secondary storage. That is why the terms virtual memory translation and logical memory translation are often conflated. These days it is becoming increasingly common to have logical translation without virtual memory.
All address accesses through a process are to logical addresses. The processor translates the logical address to page frames. If logical page exists but is mapped to secondary storage, accessing that page triggers a page fault. The operating system must handle the fault, remap the logical/virtual page to a physical page frame; load the data from secondary storage to the page frame; and restart the instructions.
Supposing that the page number is 4 and the offset is 3. Then Page 4 in the logical memory maps to frame 8 in the virtual memory. This means that the starting address of the frame is 8.
This make no sense. A logical page is virtual when it is mapped to secondary storage. If the page number is 4 the 4th logical page can:
a) have no mapping at all (access violation)
b) map to a physical page frame
c) map to a secondary storage (virtual memory)
Now, each frame will contain 4096/4= 1024 words. Does the offset imply for a word inside the frame, since the machine will always fetch a word at a time? What I mean is that does it mean the 3rd word in frame 8?
In nearly all (if not all) current processors there are no memory words; only bytes. The system bus fetches memory and the "word size" of the bus can be (and often is) different from the "word size" of the processor.
Is the particular word given to the CPU, or the entire frame? If former, then why does everyone talk about transfer in terms of frames and pages rather than words?
The process sees transfers in sizes related to the instruction being executed. The operand size can be larger or smaller than the machine word. The bus transfers data to memory and that size is frequently different from the word size of the machine.
Suppose a page fault occurs. What this means is that the particular page in not in memory. Does it mean that the physical address mapped contains some other page? Does the mapping even exist in such a case when the invalid bit is 1.
I gave the three possibilities for logical page mappings above. How those are indicated are system specific. Some systems use 2 bits to indicate a, b, or c. Others use a single bit to indicate (b) and require the operating system to determine whether it's (a) or (c).
Whether or not a page fault is triggered depended upon the state of the page table.
Generally a page fault means that the page frame is not in memory. However, it is often possible for the physical page frame to be in memory but not mapped in the page table (a soft page fault). (This occurs when the operating system has unmapped page frames to free some up but has not reallocated them.) In this case, the operating system simply needs to update the page table to point to the page frame and restart the instruction (no need to load from secondary storage).
I've read several topics about this theme but I could not get the answer. So my question is:
1) How is the block offset calculated?
I want to know not the formula but the concept of it. As I know it is quantity of cases which a block can store the address. For example If there is a block with 8 byte storage and has to store 2 byte addresses. Does its block offset is 2 bit?(So there is 4 cases to store the address (the diagram below might make easier to see what I am saying).
The block offset is simply calculated as log2 cache_line_size.
The reason is that all system that I know of are byte addressable. So you need enough bits to index any byte in the block. Although most systems have a word size that is larger than a single byte, they still support offsets of a single byte gradulatrity, even if that is not the common case.
So for the example you mentioned of an 8-byte block size with 2-byte word, you would still need 3 bits in order to allow accessing any byte. If you had a system that was not byte addressable then you could use just 2 bits for the block offset. But in practice all systems that I know of are byte addressable.
Im reading the book "Write great code: understanding the machine" by Randall Hyde, is a great and clear text but here im completely stuck with his explanation of, for example, the mov instruction.
He dissects the steps for the mov(srcReg,destMem) instruction as follows:
1. Fetch the instruction's opcode from memory.
2. Update the EIP register with the address of the byte following the opcode.
3. Decode the instruction's opcode to see what instruction it specifies.
4. Fetch the displacement associated with the memory operand from the memory location immediately
following the opcode.
5. Update EIP to point at the first byte beyond the operand that follows the opcode.
6. If the mov instruction uses a complex addressing mode (for example, the indexed addressing mode),compute the effective address of the destination memory location.
7. Fetch the data from srcReg.
8. Store the fetched value into the destination memory location.
Im lost in steps 4-6. My exact questions are:
Step 4: Why do I need this displacement, how Im gonna use it later and why?
Step5: I understand that in step 2, the EIP must "point" to the next byte where the next instruction to be executed is stored. But I dont understand why does EIP needs to be one byte beyond the operand address. I belived that EIP was concerned only with instructions/opcodes, not data.
Step6: What is exactly and effective address? Are there other types of address?
Step 4:
Some opcodes reference memory that's relative to the opcode's location. For example, a function might have a constant or static piece of data. If it does, the code may opt to place that right before the function starts (or right after it ends) and refer to it by saying "get the memory from 46 bytes earlier". That's the displacement -- it's an offset from the contents of a register (in this case, EIP), used for referencing data relative to the register's contents.
Step 5
The operands for opcodes are normally stored right after the opcode. So you might have some memory arranged like so: a b c. a is and opcode, b is the operand for a and c is the next opcode.
If you only move EIP to the end of a (so it references b), then in the next instruction cycle, the computer will assume that b is the next opcode to execute. b isn't supposed to be an opcode though; it's an operand. The computer can't tell the difference between an opcode and an operand though. It just assumes whatever EIP points to is an instruction and executes it. That's why EIP needs to be moved past the operand too.
Step 6
An "effective" address is just an absolute one (relative to the start of memory) while the "complex" address the book refers to is relative to something else (often the contents of a register).
Step 4 showed that an opcode might not refer to an absolute memory address. It could easily refer to a relative one. In fact, programs very frequently refer to addresses that are relative to some register. For example, if you wrote some_struct.data in C and compiled it for an x86 processor, it would load the address of some_struct into a register (say, EAX), then hard-code data's offset from the base of some_struct into the operand. So if there are 5 bytes of data between the start of the struct and the start of the data element, then the instruction might look like load [EAX + 5] -> EBX which means "take what's in EAX, add 5, fetch the data from that address and put it in EBX".
The thing is, the memory doesn't really understand relative addresses like this. It only understands absolute ones. So in order to access a relative address, the processor has to first add that 5 to whatever's in EAX to compute an absolute address. Then it can send that address to the memory controller and have it understood.
There are two basic types of relative addresses I've worked with (there are more I haven't).
Register relative: The processor takes the contents of a register and uses that as the address in memory. Depending on the opcode and processor support, it may also add an operand to the register as well. Step 4 was dealing with this kind of addressing, with EIP as the register the address was relative to.
Memory relative: Sometimes referred to as "indirect". The processor starts out with a register relative address, then automatically fetches the data at that address and treats it as the real address.
Wikipedia describes lots of other addressing modes on their addressing modes page.
Memory relative took me a while to understand. Say you did a memory relative load where the register contains 10 and the offset is 5. The processor will add them together (10 + 5 = 15). Then, it'll go to that address (15 in this case) and grab whatever's there. If address 15 happens to contain the value 60, then 60 will be treated as the actual address and the processor will load the contents of address 60. If you're familiar with a language with pointers (e.g. C), memory relative is like a pointer-to-a-pointer.
In real mode segmented memory model, a segment always begins on a paragraph boundary. A paragraph is 16 bytes in size so the segment address is always divisible by 16. What is the reason/benefit of having segments on paragraph boundaries?
It's not so much a benefit as an axiom - the 8086's real mode segmentation model is designed at the hardware level such that a segment register specifies a paragraph boundary.
The segment register specified the base address of the upper 16 bits of the 8086's 20 bit address space, the lower 4 bits of that base address were in essence forced to zero.
The segmented architecture was one way to have the 8086's 16-bit register architecture be able to address a full megabyte(!) of address space (which requires 20 bits of addressing).
For a little more history, the next step that Intel took in the x86 architecture was to abstract the segment registers from directly defining the base address. That was the 286 protected mode, where the segment register held a 'selector' that instead of defining the bits for a physical base address was an index into a a set of descriptor tables that held information about the physical address, permissions for access to the physical memory, and other things.
The segment registers in modern 32-bit or larger x86 processors still do that. But with the address offsets being able to specify a full 32-bits of addressing (or 64-bits on the x64 processors) and page tables able to provide virtual memory semantics within the segment defined by a selector, the programming model essentially does away with having to manipulate segment registers at the application level. For the most part, the OS sets the segment registers up once, and nothing else needs to deal with them. So programmers generally don't even need to know they exist anymore.
The 8086 had 20 address lines. The segment was mapped to the top 16, leaving an offset of the bottom 4 lines, or 16 addresses.
The Segment register stores the address of the memory location where that segment starts. But Segment registers stores 16 bit information. This 16 bit is converted to 20 bits by appending 4 bits of 0 to the right end of the address. If a segment register contains 1000H then it is left shifted to get 10000H. Now it is 20 bits.
While converting we added 4 bits of 0 to the end of the address. So every segment in memory must begin with memory location where the last 4 bits are 0.
For ex:
If a segment starts at 10001H memory location, we cannot access it because the last 4 bits are not 0.
Any address in segment register will be appended with 4 bits in right end to convert to 20bits. So there is no way of accessing such an address.
I understand what it means to access memory such that it is aligned but I don’t understand why this is necessary. For instance, why can I access a single byte from an address 0x…1 but I cannot access a half word (two bytes) from the same address.
Again, I understand that if you have an address A and an object of size s that the access is aligned if A mod s = 0. But I just don’t understand why this is important at the hardware level.
Hardware is complex; this is a simplified explanation.
A typical modern computer might have a 32-bit data bus. This means that any fetch that the CPU needs to do will fetch all 32 bits of a particular memory address. Since the data bus can't fetch anything smaller than 32 bits, the lowest two address bits aren't even used on the address bus, so it's as if RAM is organised into a sequence of 32-bit words instead of 8-bit bytes.
When the CPU does a fetch for a single byte, the read cycle on the bus will fetch 32 bits and then the CPU will discard 24 of those bits, loading the remaining 8 bits into whatever register. If the CPU wants to fetch a 32 bit value that is not aligned on a 32-bit boundary, it has several general choices:
execute two separate read cycles on the bus to load the appropriate parts of the data word and reassemble them
read the 32-bit word at the address determined by throwing away the low two bits of the address
read some unexpected combination of bytes assembled into a 32-bit word, probably not the one you wanted
throw an exception
Various CPUs I have worked with have taken all four of those paths. In general, for maximum compatibility it is safest to align all n-bit reads to an n-bit boundary. However, you can certainly take shortcuts if you are sure that your software will run on some particular CPU family with known unaligned read behaviour. And even if unaligned reads are possible (such as on x86 family CPUs), they will be slower.
The computer always reads in some fixed size chunks which are aligned.
So, if you don't align your data in memory, you will have to probably read more than once.
Example
word size is 8 bytes
your structure is also 8 bytes
if you align it, you'll have to read one chunk
if you don't align it, you'll have to read two chunks
So, it's basically to speed up.
The reason for all alignment rules are the various widths of the Cache Lines (Instruction-Cache do have 16 Byte lines for the Core2 Architecture, and the Data-Cache do have 64-Byte Lines for L1 and 128-Byte Lines for L2).
So if you want to store/load data that crosses a Cahce-Line Boundary you need to load and store both Cache-lines, which hits the performance.
So you just don't do it because of the performance hit, its that simple.
Try reading a serial port. The data is 8 bits wide.
Nice hardware designers ensure it lies on a least significant byte of the word.
If you have a C structure that has elements not word aligned ( from backwards compatibility or conservation of memory say )
then the address of any byte within the structure is not word aligned.