Operating System 8: Memory Hierarchy and Program Loading and Linking

Table of contents

1. Memory hierarchy

(1) Memory system with multi-layer structure

1.1 - Multilayer structure of memory

1.2 - Executable memory

(2) Main memory and registers

2.1 - Main memory

2.2 - Registers

(3) cache and disk cache

3.1 - Caches

3.2 - Disk caching

2. Program loading and linking

(1) Loading the program

1.1 - Absolute Loading Mode

1.2 - Relocation Loading Mode

1.3 - Dynamic Run-time Loading

(2) Links to programs

2.1 - Static Linking method

2.2 - Load-time Dynamic Linking


1. Memory hierarchy

        When the computer executes, almost every instruction involves access to the memory, so it is required that the access speed of the memory can keep up with the operating speed of the processor. In other words, the speed of the memory must be very fast to match the speed of the processor, otherwise the operation of the processor will be significantly affected. In addition, the memory is required to have a very large capacity, and the price of the memory should be very cheap. // fast, large capacity, cheap

        For such three very strict conditions, it is currently impossible to meet them at the same time . Therefore, in modern computer systems, the memory system with multi-layer structure is adopted without exception.

(1) Memory system with multi-layer structure

1.1 - Multilayer structure of memory

        For a general-purpose computer, the storage hierarchy should have at least three levels: the highest level is the CPU register, the middle is the main memory, and the bottom level is the auxiliary memory . In higher-end computers, it can also be subdivided into 6 layers of registers, cache, main memory, disk cache, fixed disk, and removable storage media according to specific functions. As shown below. // register + main storage + auxiliary storage

        In the storage level, the higher the level (closer to the CPU), the faster the access speed of the storage medium, the higher the price, and the smaller the relative storage capacity configured . Among them, registers, high-speed cache, main memory and disk cache all belong to the jurisdiction of the storage management of the operating system, and the information stored in them no longer exists after power failure. The low-level fixed disks and removable storage media are under the jurisdiction of device management, and the information they store will be preserved for a long time. //The information of the main memory will be lost when the power is off, and the auxiliary memory can save the information for a long time

1.2 - Executable memory

        In the storage hierarchy of a computer system, registers and main memory are also called executable memory . For the information stored in it, compared with the information stored in the auxiliary storage, the access mechanism adopted by the computer is different, and the required time is also different.

A process can access executable memory with a single load or store instruction         in a few clock cycles . However, the access to the auxiliary storage needs to be realized through the I/O device. Therefore, the access will involve the operation of interrupts, device drivers and physical devices, and the time required is much higher than that of accessing the executable memory. Generally, the difference is 3 orders of magnitude or even more. //The access mechanisms for main memory and auxiliary memory are different, and the access efficiency is also different.

        The storage media of different levels are managed uniformly by the operating system. The storage management of the operating system is responsible for the allocation and recovery of executable memory, and provides a management mechanism for data movement between storage levels, such as data movement between main memory and disk cache, cache and main memory, etc. The device and file management provides a management mechanism for auxiliary storage according to the needs of users. //Storage management refers to the management of executable memory, device and file management is aimed at the management of auxiliary storage

(2) Main memory and registers

2.1 - Main memory

        The main memory, referred to as memory or main memory, is the main component of a computer system and is used to save programs and data when a process is running. It is also called executable memory.

        Typically, a processor fetches instructions and data from main memory , places the fetched instructions into the instruction register, and loads the data it reads into the data register; data stored in main memory.

        Since the access speed of the main memory is much lower than the speed of the CPU executing instructions, in order to alleviate this contradiction, registers and caches are introduced in the computer system.

2.2 - Registers

        The register has the same speed as the processor, so the access to the register is the fastest , and it can fully coordinate with the CPU, but the price is very expensive, so the capacity cannot be made large.

        In early computers, the number of registers was only a few, which were mainly used to store data when the processor was running to speed up memory access. For example, registers were used to store operands, or used as address registers to speed up address conversion. With the development of VLSI (Very Large Scale Integration), the cost of registers is also rapidly decreasing. In the current microcomputer system and large and medium-sized computers, the number of registers has increased to dozens to hundreds, and the word of the register The length is generally 32 bits or 64 bits; and in small embedded computers, the number of registers is still only a few to a dozen, and the word length of the registers is usually only 8 bits.

(3) cache and disk cache

3.1 - Caches

        Cache is an important part of modern computer structure. It is a storage between registers and memory . Significantly improve program execution speed . The cache capacity is much larger than the registers, and about two to three orders of magnitude smaller than the memory, from tens of KB to several MB, and the access speed is faster than the main memory. In computer systems, in order to ease the contradiction between memory and processor speed, caches are set in many places. // Two or more levels of cache can be set

3.2 - Disk caching

        Since the current disk I/O speed is much lower than the access speed to the main memory, in order to alleviate the speed mismatch between the two, a disk cache is set up, which is mainly used to temporarily store a part of frequently used disk data and information , to reduce the number of disk accesses. But the disk cache is different from the cache, it is not a kind of actual memory itself, but uses part of the storage space in the main memory to temporarily store the information read (or written) from the disk . The main memory can also be regarded as the cache of the auxiliary memory, because the data in the auxiliary memory must be copied to the main memory before it can be used, and vice versa, the data must first be stored in the main memory before it can be output to the auxiliary memory.

2. Program loading and linking

        To run a user program in the system, it must first be loaded into the memory, and then converted into an executable program, usually through the following steps:

  • Compile , the compiler (Compiler) compiles the user source program to form several object modules (ObjectModule)
  • Linking , the linker (Linker) links together a set of target modules formed after compilation and the library functions they need to form a complete load module (Load Module)
  • Loading , the loading module is loaded into memory by the loader (Loader)

(1) Loading the program

        When loading a load module into memory, there are three loading methods as follows:

1.1 - Absolute Loading Mode

        When computer systems were small and could only run a single program, it was entirely possible to know where the program would reside in memory. At this time, the absolute loading method can be used. After the user program is compiled, it will generate the object code of the absolute address (that is, the physical address) . For example, it is known in advance that the user program resides at the location starting from R, and the object module generated by compiling the program can be expanded upward from R. The absolute loader loads programs and data into memory according to the address in the load module. After the loaded module is loaded into the memory, since the relative address in the program (that is, the logical address) is exactly the same as the actual memory address, there is no need to modify the address of the program and data . // No need to convert logical address and physical address

1.2 - Relocation Loading Mode

        After the load module is loaded into the memory by the relocatable load program, all the logical addresses in the load module will be different from the physical addresses actually loaded into the memory . // Need to convert logical address to physical address

        For example, there is an instruction LOAD(1, 2500) at unit 1000 of the user program, the function of this instruction is to fetch the integer 365 in unit 2500 to register 1. But if the user program is loaded into memory unit 10000~15000 without address conversion, when the instruction in unit 11000 is executed, it will still fetch the data from unit 2500 to register 1, resulting in data error.

        It can be seen that the correct method should be to modify the address 2500 in the index finger to 12500, that is, add the logical address 2500 in the instruction to the starting address 10000 of this program in the memory to get the correct physical address 12500 . In addition to modifying the data address, the instruction address must also be modified, that is, add the logical address 1000 of the instruction to the initial address 10000 to obtain the absolute address 11000. //Static address conversion, no modification after conversion

        Usually, the process of modifying the instruction and data addresses in the target program during loading is called relocation . And because the address conversion is usually completed once when the process is loaded, and will not change later, it is called static relocation . //This method does not allow the program to move locations in memory while it is running

1.3 - Dynamic Run-time Loading

        If the program moves in the memory, it means that its physical location has changed. At this time, the address (absolute address) of the program and data must be modified before it can run. In practice, the location of the program in the memory may often change during the running process. For example, in a system with the swap function, a process may be swapped out and swapped in multiple times. The position after entry is usually different. In this case, dynamic runtime loading should be used. // use the background

        The loader at dynamic runtime does not convert the logical address in the loaded module into a physical address immediately after loading the loaded module into the memory, but postpones this address conversion until the program is actually executed . Therefore, all addresses after being loaded into memory are still logical addresses. In order to make the address translation not affect the execution speed of the instruction, this method needs the support of a relocation register .

(2) Links to programs

        After the source program is compiled, a set of target modules can be obtained. The function of the linker is to assemble this set of object modules and the library functions they need into a complete load module . When linking the target module, according to the time of linking, the links can be divided into the following three types:

2.1 - Static Linking method

        Before the program runs, the target modules and their required library functions are linked into a complete assembly module, which will not be disassembled later . We call this way of linking in advance the static linking method.

        For example, the figure below shows three target modules A, B, and C obtained after compilation, and their lengths are L, M, and N, respectively. There is a statement CALL B in module A, which is used to call module B. There is a statement CALL C in module B, which is used to call module C. Both B and C are external call symbols. When assembling these object modules into a load module, the following two problems must be solved: // Link in advance: load all the resources used by the program into the memory at one time

        Modify the relative address . In all object modules generated by the compiler, relative addresses are used, and their start addresses are all 0, and the addresses in each module are calculated relative to the start address. After being linked into a loading module, the starting addresses of the original modules B and C in the loading module are no longer 0, but are L and L+M respectively, so the relative addresses in modules B and C must be modified at this time, That is, add L to all the relative addresses in the original B, and add L+M to all the relative addresses in the original C.

        Transform external call symbols . Transform the external call symbols used in each module into relative addresses, such as transforming the start address of B into L, and transforming the start address of C into L+M. A complete load module formed by this first link is also called an executable file. Usually it is no longer disassembled, and it can be directly loaded into the memory when it is to be run. This kind of linking method that is linked in advance and will not be disassembled later is called a static linking method .

2.2 - Load-time Dynamic Linking

        This refers to a group of target modules obtained after compiling the user source program. When loading into the memory, the linking method is adopted while loading and linking . That is, when loading an object module, if an external module call event occurs, it will cause the loader to find the corresponding external object module and load it into the memory . Load-time dynamic linking has the following advantages: // Load-time dynamic linking

  • Easy to modify and update . Modifying or updating one of the object modules in statically linked load modules requires reopening the load modules. Not only is this inefficient, but it is sometimes impossible. If the dynamic link method is adopted, since each object module is stored separately, it is very easy to modify or update each object module.
  • It is convenient to realize the sharing of target modules . When using the static link method, each application module must contain a copy of its target module, and the sharing of the target module cannot be realized. However, when the dynamic link method is used when loading, the OS can easily link an object module to several application modules, so that multiple application programs can share the module.

2.3 - Run-time Dynamic Linking

        In many cases, when the application is running, the modules to be run may be different each time. However, since it is impossible to know in advance which modules are to be run this time, all possible modules to be run can only be loaded into the memory, and all of them are linked together when loading. Obviously this is inefficient, because often some object modules will not run at all. A typical example is an object module used for error handling. If the program does not have errors during the entire running process, the module will obviously not be used.

        The run-time dynamic link method that has become popular in recent years is an improvement on the load-time link method . This linking method is to defer the linking of some modules until the program is executed . That is, during execution, when a called module is found not yet loaded into the memory, the OS will immediately find the module, load it into the memory, and link it to the calling module. All target modules that are not used in the execution process will not be loaded into the memory and linked to the loading module, which can not only speed up the loading process of the program, but also save a lot of memory space. // dynamic linking at runtime

// The loading and linking of the program develops from static to dynamic, and the preparation in advance is delayed until the program is used, which can save a lot of memory space. The only problem is that the program calls resources when it is running, which will take up extra operating time

Guess you like

Origin blog.csdn.net/swadian2008/article/details/131517285