When people explain the difference between threads and fibers, they often refer to the fact that fibers are in "user space". What does "user space" mean?
Related
Here in this lecture, some extreme implementations of a page table are discussed as well as some reasonable ones.
One of the extreme cases was to allocate a flat array that maps every possible virtual address to a physical address.
At the minute 19:19 (which the given link will start at), the lecturer says that he's talking about a flat array of pointers to PTEs. And then mentions that he could've done something even more stupid which is to use an array of actual page table entries.
Why would having an array of pointers to PTEs be better that having an actual array of PTEs?
He is talking about a 32 bit system with an address of 4 bytes, But PTE is also 4 bytes.
Isn't having an array of pointers more wasteful because it'll take double the space (4 bytes for the pointer and 4 for the PTE)?
Also, I believe that allocating a lot of PTEs that're spread across the physical memory would cause fragmentation and will be hard to manage, as opposed to creating just an array of PTEs which will be one chunk of memory that does not need a lot of management.
Why would having an array of pointers be a better case?
If you have many virtual address spaces that are all 4 GiB each; you might find that:
a large area (e.g. 1 GiB) is used for kernel and needs to be the same in all virtual address spaces. Because this is the same in all virtual address spaces, any modification in this area needs to modify every virtual address space at the same time.
various areas will be shared by 2 or more virtual address spaces for other reasons - memory mapped files, shared libraries, shared memory, "copy on write" areas caused by "fork()", etc.
some areas will be the same in the same virtual address space (e.g. refer to the same "read only physical page full of zeros" to implement an "allocate on write" strategy)
a lot of space will be entirely unused (maybe an average of 2 GiB per virtual address space)
For anything that's used in multiple places; a "pointer to PTE" would give you a single PTE that can be modified regardless of how many places the page is used.
For one example; let's say you have a "C standard library" shared by 40 different processes (and included in 40 different virtual address spaces), but part of the library's code is still on disk and the PTE/s for those parts say "not present". When any process needs that part of the shared library you get a page fault (because it's not present yet) and the OS has to fetch the page from disk. In this case "pointer to PTE" means the OS can change one PTE (from "not present" to "present") and doesn't need to figure out how many PTEs need to be updated, then update 40 different PTEs for 40 different virtual address spaces/processes.
Isn't having an array of pointers more wasteful because it'll take double the space (4 bytes for the pointer and 4 for the PTE)?
Array of pointers to PTEs would waste more space, but it's hard to say how much space (it wouldn't be "double" because lots of PTEs would be used multiple times, and might be closer to 50% more space). Array of PTEs would waste more CPU time (in kernel's code trying to manage everything) instead, and (if you take into account kernel using its own additional data/memory to be able to figure out which pages are shared where) it might actually cost more memory.
However...
They are both relatively awful; and I'd expect that the lecturer is preparing to introduce multi-level paging (where "one pointer to PTE per page" gets replaced with "one pointer to group of PTEs"), which is what most real CPUs use.
An overhead incurs when walking the page tables to find a translation. Every now and then a new paper is published explaining how their implementation is superior. Some suggest hashing the page tables. I suggest you don't over think it, understand the principles of walking the page tables and a simple implementation is enough to get a grasp.
I have just started learning rust, and it is my first proper look into a low level language (I do python, usually). Part of the tutorial explains that a string literal is stored on the stack, because it has a fixed (and known) size; it also explains that a non-initialised string is stored on the heap, so that its size can grow as necessary.
My understanding is that the stack is much faster than the heap. In the case of a string whose size is unknown, but I know it will not ever require more than n bytes, does it make sense to allocate space on the stack for the maximum size, instead of sticking it on the heap?
The purpose of this question is not to solve a problem, but to help me understand, so I would appreciate verbose and detailed answers!
The difference in performance between the stack and the heap comes due to the fact that objects in the heap may change size at run time, and they must then be reallocated somewhere else in the heap.
Now for the verbose part. Imagine you have an integer i32. This number will always be the same size, so any modifications made to it will occur in place. When it goes out of scope (it stops being needed in the program) it will either be deleted, or, a more efficient solution, it will be deleted along with the whole stack it belongs to.
Now you want to create a String. So you create it in the heap and give it a value. And then you modify it and add some characters to it. Now two things can happen.
There is free memory after the string, so the allocator uses this memory to write the new part.
There already is an object allocated in the memory right after the string, and of course, you don't want to overwrite it. So the allocator looks for the next free memory space with enough size to hold the new string and copies into it that string. Then deletes the old one, freeing that memory.
As you can see in the heap the number of operations to be made is incredibly higher than in the stack, so its performance will be lower.
Now, in your case, there are some methods specifically for memory reservation. String::reserve() and String::reserve_exact(). I would recommend you to look at the documentation for Rust always. Usually there already is a std method for what you want.
I have a good bit of experience with MKMapView's use of specific coordinates for locations, but is there a way to denote a certain range, such as a block of a street? A way to say "the 5600 block of Main Street" or something similar, rather than a specific point? I'd love it if you could even define the side of the street, but the block at least would be usable.
Or would you just need to define it using point-pairs, so "this block" is defined as the space between the startOfBlockCoordinate and endOfBlockCoordinate points?
I would offer code samples and such, but I legitimately don't know where to start. Every time I try to do research on the topic, I end up getting results about "blocks" (like segments of code in Objective-C) and "blocks" (like preventing a user from doing something).
What is the difference, if any, between a context diagram and a level 0 diagram?
There are some conflicts in the literature about these two terms.
Refer page 54 of this book for example. It is highly rated on google books and is a standard text in many schools. It says that a context diagram is the same as a Level 0 DFD. This one disagrees on page 210.
I'll first address the notion of "levels".
As we know, initially, the whole of the system is represented by one big block, and interactions with the system are clearly depicted. Initially, we are seeing the system with a naked eye.
Now, think of yourself holding something like a microscope. You place the lens above the system block and zoom in. This "zooming in" takes you to the next level in the hierarchy. So now, you see that the system is made up of a number of blocks.
You pick up any of the sub-blocks, and then zoom in again, thus going to the next level and so on.
So we see that there is a hierarchy of diagrams, with each level taking us to the next level of detail. The only bone of contention that now remains is name of the first level (The view with the naked eye).
As you can see, the question is not very objective, hence the ambiguity.
We can have :
Context Diagram ->
Level 0 DFD ->
-> Level n DFD</pre>
OR
Context Diagram/Level 0 DFD
->Level 1 DFD
->Level n DFD
It boils down to which one looks better. In my personal opinion , the first hierarchy is more apt. This is because initially, all we see is the system and the context within which it operates. I feel that anyone who understands the explanation should't worry much about the nomenclature.
Refer this for more.
A very difficult discussion.
My thoughts:
A context diagram only has 1 process, while a DFD level 0 can have more.
The context diagram established context at the system to be developed that is it represents the interaction at the system with various external entities.
Where data flow diagram is a simple graphical notation that can be used to represent a system in the term of input data to the system,various processing carried out on this data and the output generated by the system. It is simple to understand and use.
Taking my first course in assembly language, I am frustrated with cryptic error messages during debugging... I acknowledge that the following information will not be enough to find the cause of the problem (given my limited understanding of the assembly language, ColdFire(MCF5307, M68K family)), but I will gladly take any advice.
...
jsr out_string
Address Error (format 0x04 vector 0x03 fault status 0x1 status reg 0x2700)
I found a similar question on http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&thread.id=271, regarding on ADDRESS ERROR in general.
The answer to the question states that the address error is because the code is "incorrectly" trying to execute on a non-aligned boundary (or accessing non-aligned memory).
So my questions will be:
What does it mean to "incorrectly" trying to execute a non-aligned boundary/memory? If there is an example, it would help a lot
What is non-aligned boundary/memory?
How would you approach fixing this problem, assuming you have little debugging technique(eg. using breakpoints and trace)
First of all, it is possible that isn't the instruction causing the error. Be sure to see if the previous or next instruction could have caused it. However, assuming that exception handlers and debuggers have improved:
An alignment exception is what occurs when, say 32 bit (4 byte) data is retrieved from an address which is not a multiple of 4 bytes. For example, variable x is 32 bits at address 2, then
const1: dc.w someconstant
x: dc.l someotherconstant
Then the instruction
mov.l x, %r0
would cause a data alignment fault on a 68000 (and 68010, IIRC). The 68020 eliminated this restriction and performs the unaligned access, but at the cost of decreased performance. I'm not aware of the jsr (jump to subroutine) instruction requiring alignment, but it's not unreasonable and it's easy to arrange—Before each function, insert the assembly language's macro for alignment:
.align long
func: ...
It has been a long time since I've used a 68K family processor, but I can give you some hints.
Trying to execute on an unaligned boundary means executing code at an odd address. If out_string were at an address with the low bit set for example.
The same holds true for a data access to memory of 2 or 4 byte data. I'm not sure if the Coldfire supports byte access to odd memory addresses, but the other 68K family members did.
The address error occurs on the instruction that causes the error in all cases.
Find out what instruction is there. If the pc matches (or is close) then it is an unaligned execution. If it is a memory access, e.g. move.w d0,(a0), then check to see what address is being read/written, in this case the one pointed at by a0.
I just wanted to add that this is very good stuff to figure out. I program high end medical imaging devices in my day job, but occasionally I need to get down to this level. I have found and fixed more than one COTS OS problem by being able to track down just this sort of problem.