Memory block wear leveling strategy optimization method
By dividing large memory blocks and small memory blocks in nonvolatile memory, wear difference control and clock allocation strategies are adopted to solve the problem of wear unevenness caused by different write tolerances of different NVMs, and wear balance and service life are achieved.
Patent Information
- Application Number
- CN202411306612.3
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2024-09-19
- Publication Date
- 2024-12-20
AI Technical Summary
Different types of nonvolatile memory (NVM) have great differences in write tolerance. The existing memory allocators have failed to effectively optimize the wear problem, resulting in excessive wear of some NVMs, affecting their service life.
A memory block wear equalization strategy is proposed. By dividing large memory blocks and small memory blocks, wear difference control and clock allocation strategies are adopted to design wear equalization algorithms separately, and wear values are monitored and optimized in real time to avoid overuse and ensure wear equalization distribution.
It effectively extends the service life of NVM, is better than the traditional wear equalization strategy, significantly improves memory allocation efficiency and system reliability, reduces wear differences, and avoids resource waste.
Smart Images

Figure BDA0005049405430000061 
Figure BDA0005049405430000081 
Figure BDA0005049405430000091
Abstract
Description
Technical Field
[0001] The invention belongs to the field of non-volatile memory, and in particular relates to a method for optimizing a memory block wear leveling strategy. Background Art
[0002] Compared with traditional memory (DRAM, NAND Flash), the new non-volatile memory (NVM) has the advantages of non-volatility, byte addressability, high storage density, and read and write latency similar to DRAM. It is considered a candidate to replace DRAM, but it also has the disadvantage of low write tolerance, and its write times are much lower than DRAM. In addition, different NVMs have large differences in write tolerance due to their different materials and manufacturing processes. NVM has the advantages of traditional memory and external memory, so it can be used as memory for byte access and as external memory for data storage. Since DRAM faces bottlenecks in manufacturing technology and memory capacity growth is slow, more and more scholars are focusing on using NVM as memory. Like DRAM, NVM can be directly connected to the memory bus through the DIMM slot, and can use a unified addressing method with DRAM, so that the CPU can access non-volatile memory by byte through Load / Store instructions.
[0003] However, using NVM as memory faces two severe challenges: (1) The write tolerance between different NVMs varies greatly. In heterogeneous non-volatile memory scenarios, different NVMs have different write tolerances, and most existing memory allocators do not take this into account, resulting in memory allocation being concentrated on a certain NVM, which will increase the wear on the NVM. (2) The memory allocator must implement a wear optimization strategy to prevent excessive wear of the NVM storage medium. Traditional DRAM allocators often reuse released memory blocks, which will increase NVM wear, while existing NVM memory allocators focus more on persistence functions. Therefore, when designing a memory allocator, it is necessary to formulate a corresponding wear optimization strategy to extend the life of the NVM. Summary of the invention
[0004] Based on the above challenges, the present invention proposes a memory block wear leveling strategy optimization method and a wear difference control and clock distribution strategy, which adopts different wear leveling algorithms for large memory blocks and small memory blocks respectively to improve the service life of NVM.
[0005] A memory block wear leveling strategy optimization method comprises the following steps:
[0006] S1. Divide the NVM memory blocks into large memory blocks and small memory blocks, so that memory management is more flexible and targeted. By clearly dividing the range of small memory blocks, large memory blocks and super large memory blocks, corresponding wear leveling strategies can be implemented for different memory block types, thereby improving the efficiency of memory allocation and the reliability of the overall system. The range of small memory blocks is less than or equal to 4KB, the range of large memory blocks is greater than 4KB and less than or equal to 1MB, and those greater than 1MB are super large memory blocks. The present invention only performs wear leveling optimization on small memory blocks and large memory blocks.
[0007] S2. A field Span_wear_count is added to the block header structure of the interval Span (a continuous memory area) to record the wear value of the corresponding Span of the large memory block and the small memory block; for the large memory block, the value of this field is increased by 1 each time it is allocated, and for the small memory block, the value of this field is increased by 1 each time it is searched in the Span. The use of each Span can be monitored in real time, especially by accurately recording the number of allocations to ensure the accuracy of wear data, which helps prevent overuse of certain memory blocks.
[0008] S3. In the NVM memory pool, add the Max_Span_WearCount variable to record the wear value of the most severely worn Span in the memory pool; add the max_wear_Span_ptr pointer to point to the first node in the linked list composed of multiple Span nodes whose wear value is equal to Max_Span_WearCount. When allocating memory, start allocating from the head of the linked list (that is, the node with a wear value less than Max_Span_WearCount). If the wear values of all nodes in the linked list are less than Max_Span_WearCount, max_wear_Span_ptr is set to NULL. The most severely worn Span in the memory pool can be effectively recorded, and those with less wear can be allocated preferentially, thereby achieving a balanced distribution of wear. This method ensures the rationality of memory allocation and avoids excessive use of certain spans.
[0009] S4. In the thread cache, set the wear value threshold Wear_Threshold so that the wear value of all spans in the thread cache does not exceed this threshold; when the wear value of a span reaches the wear value threshold, it is prohibited to continue to allocate memory to avoid excessive wear of the span; add an unavailable state (unavailable) to the span in the thread cache, and manage these unallocatable small memory blocks through the unavailable_array array, which can effectively prevent excessive wear of the memory block. By setting the wear threshold and prohibiting allocation when the threshold is reached, the service life of the memory can be significantly improved. Introducing the unavailable state (unavailable) for the span in the thread cache and managing the unallocatable small memory blocks through the unavailable_array array can further optimize the management efficiency of the memory block. This method ensures the reasonable allocation of memory blocks under the wear threshold and avoids waste of resources.
[0010] Each linked list node in unavailable_array has a fixed one-to-one correspondence with the size of the small memory block, for example, index 0 corresponds to 64 bytes, index 1 corresponds to 128 bytes, and so on.
[0011] S5. For small memory blocks, a clock distribution algorithm is used for uniform distribution, including the following process:
[0012] S5.1. Modify the block header structure of Span, change the original available_free_start field to a bitmap field (a bitmap indicating the allocation status of small memory blocks, each bit indicates the usage of a small memory block), delete the small_block_header_node field of the small memory block header node; add the index cur_pos pointing to the next small memory block to be allocated and the last_pos field pointing to the end position of the bitmap. This makes memory allocation more uniform and reduces the generation of memory fragmentation.
[0013] A bitmap is implemented: each bit in the bitmap represents the allocation status of the corresponding small memory block, 0 means it is in use, and 1 means it is free. The bitmap is used to ensure that only free memory blocks after cur_pos are found. It can intuitively represent the allocation status of small memory blocks and ensure the effective use of memory blocks. By clearly indicating the usage of each memory block, the efficiency and accuracy of the allocation process can be significantly improved.
[0014] S5.2, when allocating memory blocks, search for the first available memory block clockwise from cur_pos. If no available memory block is found when reaching last_pos, it means that one round of allocation is over, span_wear_count increases and the search starts again. This avoids the overuse of some memory blocks, thereby achieving wear leveling and extending the service life of NVM.
[0015] Beneficial effects of the present invention:
[0016] The present invention analyzes and optimizes the simple wear leveling strategy, and proposes an optimized wear leveling strategy - wear difference control and clock allocation strategy. This strategy designs different wear leveling algorithms for large memory blocks and small memory blocks respectively. For large memory blocks, the strategy designs a wear difference control algorithm to control the wear difference between large memory blocks within a dynamic range. For small memory blocks, the memory allocator HPNMalloc designs a clock allocation algorithm to ensure that the probability of each small memory block being allocated is consistent, so as to achieve wear balance between small memory blocks as much as possible. Experiments show that under the premise of ensuring operating performance, this strategy has a better wear optimization effect for small memory blocks in the [0,1024] byte range and mixed memory blocks in the [0,10240] byte range (when both small memory blocks and large memory blocks exist) than Wamalloc and NVMalloc, which adopt a simple wear leveling strategy. BRIEF DESCRIPTION OF THE DRAWINGS
[0017] Figure 1 It is the internal structure of the memory pool;
[0018] Figure 2 Cache internal structures for threads;
[0019] Figure 3 This is the relationship diagram of the five state transitions of Span;
[0020] Figure 4 It is the Span block header structure;
[0021] Figure 5 Flowchart for memory allocation interface;
[0022] Figure 6 It is the flow chart of memory release interface;
[0023] Figure 7 Comparison of the average number of writes to the basic storage units of four memory allocators;
[0024] Figure 8 Comparison of wear variance of basic unit number of four memory allocators;
[0025] Fig. 9Compare the performance of HPNMalloc, Wamalloc and NVMalloc in single thread;
[0026] Fig.10 Performance comparison of HPNMalloc, Wamalloc and NVMalloc running under 10 threads. DETAILED DESCRIPTION
[0027] The following will clearly and completely describe the technical solution of the present invention based on the drawings in the implementation examples of the present invention. The implementation described in the description is only a part of the embodiments of the present invention and cannot cover all implementation examples. Based on the embodiments of the present invention, all other embodiments obtained by ordinary technicians in this field without creative work are within the scope of protection of the present invention. A memory block wear leveling strategy optimization method specifically includes:
[0028] 1. Wear Difference Control Algorithm
[0029] In order to perform fine-grained wear leveling, the memory allocator HPNMalloc adds a field Span_wear_count to the Span block header structure to record the wear value of the interval Span. The wear value is equivalent to the number of times the Span is allocated. For large memory blocks, the value of this field increases by 1 each time it is allocated. For small memory blocks, the clock allocation algorithm stipulates that the value of this field increases by 1 each time a search is performed in the Span.
[0030] Instructions attached Figure 1For the internal structure of the NVM memory pool, the memory allocator HPNMalloc will set a variable Max_Span_WearCount for the memory pool. This variable records the wear value of the most severely worn Span in the memory pool. At the same time, the memory allocator will set a pointer max_wear_Span_ptr for each linked list (a linked list composed of multiple Span nodes) in the lb_free_array in the memory pool. This pointer points to the first node in each linked list whose wear value is equal to Max_Span_WearCount. If all nodes in the linked list are less than the Max_Span_WearCount, max_wear_Span_ptr is set to NULL. The wear difference control algorithm ensures that the wear value of the node before the max_wear_Span_ptr pointer is less than the node pointed to by the pointer, and the wear value of the node after the pointer is the same as the wear value of the node pointed to by the pointer. When allocating, it starts from the head of the linked list, that is, from the node whose wear value is less than the Max_Span_WearCount value. The design mainly has the following two effects: (1) Max_Span_WearCount is a wear threshold. When allocating, it will give priority to the spans with wear values less than this threshold, so as to avoid the spans being allocated repeatedly, resulting in increasing wear differences of spans in the memory pool. (2) It can ensure that the span with the largest wear value in the memory pool is allocated last, thereby slowing down the wear speed of the corresponding storage medium.
[0031] The value of Max_Span_WearCount changes dynamically. When the Span is returned from the thread cache to the memory pool, the wear value of the Span is compared with the value of Max_Span_WearCount. If it is greater, the max_wear_Span_ptr pointers of all linked lists in Max_Span_WearCount and lb_free_array are updated.
[0032] In the thread cache, a wear value threshold Wear_Threshold is also set. The wear difference control algorithm ensures that the wear value of all spans in the thread cache does not exceed the wear value threshold. When the wear value of a span reaches the wear value threshold, no matter whether there are free memory blocks inside the span, its internal memory can no longer be allocated, thereby avoiding excessive wear of the span. At the same time, the wear difference strategy adds an unavailable state and an unavailable_array array to the spans in the thread cache. Similar to watting_for_use_array, each element in unavailable_array also stores the head node of the linked list. The linked list nodes after the head node represent a span of 4KB in size. The span of a specific linked list node can only allocate a small memory block of a specific size. For example, the span represented by the linked list node at index 0 can only allocate a small memory block of 64 bytes, and the span represented by the linked list node at index 1 can only allocate a small memory block of 128 bytes. And so on, the spans represented by the nodes are all in the unavailable_array state. As shown in the attached manual Figure 2 This is the internal structure diagram of the thread cache after adding unavailable_array.
[0033] After adding the unavailable state, there are five states for spans in the thread cache: in_use, watting_for_use, fully_allocated, unallocated, and unavailable. Figure 3 This is a conversion relationship diagram between the five states of Span. It can be seen from the figure that the in_use state can be transformed into the unavailable state. The transformation process is as follows: When a Span in the in_use state is completed after a round of search, its wear value will be increased by 1 and compared with the Wear_Threshold. If its wear value is equal to the Wear_Threshold, it indicates that the wear value of the Span has reached the wear threshold specified by the thread, then the Span will be transformed from the in_use state to the unavailable state, and the Span will be added to the end of the corresponding linked list of unavailable_array. If all the small memory blocks in the Span in the unavailable state are released, then the Span will be returned to the memory pool.
[0034] In addition, the value of Wear_Threshold is not fixed. The threshold changes when the thread cache applies for Span from the memory pool due to insufficient memory. If the value of Wear_Threshold increases, HPNMalloc will change the state of the Span corresponding to the nodes in all linked lists in unavailable_array from unavailable to watting_for_use, and remove them from unavailable_array and add them to the end of the corresponding linked list in watting_for_use_array.
[0035] The entire wear difference control algorithm process is shown in Algorithm 1:
[0036] Algorithm 1 Wear difference control algorithm
[0037]
[0038] The algorithm consists of two parts. The first part is lines 1-8 of code. This part first obtains a certain amount of spans from the memory pool for memory cache. The Cache_Spans_Num variable in the algorithm indicates the number of spans obtained. HPNMalloc sets the value of Cache_Spans_Num to 16. Then, the wear values of these spans are compared to obtain the maximum wear value Max_Cache_Span_Wear_Count, which is used to update the subsequent Wear_Threshold value.
[0039] The second part is lines 9-18 of code. First, the Max_Span_WearCount value in the memory pool is obtained. Then the algorithm specifies a wear growth value Wear_Growth_Value for the thread pool. This value can be set by the user to control the growth rate of the Span wear value. Then, the difference between Max_Span_WearCount and Max_Cache_WearCount is compared. If the difference between the two is less than Wear_Growth_Value, then the value of Wear_Threshold becomes the sum of Wear_Threshold and Wear_Growth_Value. If it is greater than or equal to Wear_Growth_Value, then W The value of ear_Threshold is the value of Max_Span_WearCount. This formula takes into account both the wear of the span in the thread cache and the frequency of the span in the thread returning to the memory pool. If the user wants to achieve wear balance as much as possible, the Wear_Growth_Value can be set smaller to ensure that the difference in wear values between the span in the thread cache and the span in the memory pool is as small as possible. If the user wants to ensure the performance of HPNMalloc, the Wear_Growth_Value can be set larger to ensure that the span can exist in the thread cache longer, but the wear leveling effect will be reduced. Afterwards, if the value of Wear_Threshold changes, the spans corresponding to the nodes in all linked lists in unavailable_array are removed from unavailable_array and added to the end of the corresponding linked list in watting_for_use_array.
[0040] 2. Clock Distribution Algorithm
[0041] When a thread applies for small memory, the memory allocator HPNMalloc will divide the small memory blocks from the corresponding Span in the thread cache and allocate them to the thread. The allocation and release frequency of small memory blocks is more frequent than that of large memory blocks. Therefore, the present invention designs a memory block clock allocation algorithm to perform wear leveling on small memory blocks. The main idea is to use directed sequential allocation for the small memory blocks inside the Span so that each small memory block has the same probability of getting an allocation opportunity.
[0042] The memory allocator HPNMalloc needs to make some changes to the span header when using the clock allocation algorithm. Figure 4It is the modified Span block header structure. First, it adds the wear value wear_count field to record the number of span allocations. Secondly, the original available_free_start field is modified to a bitmap field and the small_block_header_node field is deleted. Each bit in the bitmap represents the allocation status of the corresponding small memory block. Through the bitmap, the available small memory blocks can be obtained and allocated. Finally, in order to realize the sequential allocation of small memory blocks within the Span, the memory allocator HPNMalloc also adds cur_pos and last_pos fields. The meaning and function of each field are introduced in detail below.
[0043] As mentioned above, if Span is used to allocate small memory blocks, then Span_category indicates the type of small memory blocks. Since there are 64 small memory blocks, its value range is 0-63. The value of Span_category is 0, and the corresponding small memory block size is 64B. The value of Span_category is 1, and the corresponding small memory block size is 128B, and so on. Taking 64B as an example, the usage status of the small memory blocks inside the Span is represented by a 64-bit diagram. The bit diagram index starts from 0, where each bit establishes a mapping relationship with the corresponding memory block according to the high and low addresses. The bits of the low addresses correspond to the small memory blocks of the low addresses. The value of the bit represents the usage status of the small memory blocks, where 0 indicates that the corresponding small memory blocks are in use, and 1 indicates that the corresponding small memory blocks are in an idle state. The core idea of the memory block clock allocation algorithm is that the small memory blocks inside the Span can only be allocated in a clockwise direction, that is, they can only be allocated from low addresses to high addresses. The value of cur_pos is the next memory block index number of the most recently allocated memory block allocated in a clockwise direction, and the value of last_pos is the index number of the last small memory block plus 1, indicating the end of the bit diagram. When searching for an available memory block, start from the cur_pos position and search for the available memory block in a clockwise direction. If found, the starting address of the available memory block is returned. If no available memory block is found at the end of the position diagram, indicating that a round of allocation is over, the wear value Span_wear_count of the Span will be increased by 1, and then it will be determined whether the Span is available. If available, the search will start from the beginning.
[0044] For the allocation of small memory blocks, the traditional approach is to use a bit-by-bit search method for the bitmap, that is, starting from the cur_pos position, until the first bit is 1. Since the efficiency of bit-by-bit search is low, the paper optimizes the search of the bitmap to a certain extent, mainly through bit operations, mapping functions, and auxiliary arrays to find the next free memory block. The allocation process of the memory block clock allocation algorithm is shown in Algorithm 2.
[0045] Algorithm 2 Clock Distribution Algorithm
[0046]
[0047]
[0048] The algorithm consists of two parts. The first part is lines 1-10 of code, which mainly checks whether there are free small memory blocks that meet the requirements inside the Span. First, use the bitmap to determine whether there are free small memory blocks inside the Span. If not, return NULL. Check whether cur_pos has reached the end of the bitmap. If so, it means that a round of allocation has ended. Then add 1 to the wear value of the Span and check whether the wear value of the Span is equal to the thread wear threshold. If it is equal, then move the Span into the unallocatable linked list, and the free memory blocks inside it can no longer be allocated. When all the used memory blocks inside the Span are released, return the Span to the memory pool. If the wear value of the Span does not exceed the wear threshold, set cur_pos to 0 and continue to search for the next free memory block from the beginning.
[0049] The second part is lines 11-28 of code, which mainly searches for the specific location of the free memory block. To find the next free memory block starting from cur_pos, this paper mainly uses bit operations, mapping functions and auxiliary arrays for optimization. First, the bitmap is processed by two bit operations. The first bit operation sets all the bits before cur_pos to 0. This operation is to prevent finding the free memory block before cur_pos. The second bit operation is used to retain the bit with the lowest bit value of 1 and set all the bits after it to 0. Then the entire bitmap is divided into two parts, the part from the 1st bit to the 32nd bit is the first half, and the part from the 33rd bit to the 64th bit is the second half. First, determine whether there is a bit set to 1 in the first half. If so, find the position of the lowest bit set to 1 in the first half. The search method is shown in Algorithm 4.3. The first half is regarded as a 32-bit unsigned integer input into the algorithm. The core of the algorithm is to establish a mapping between the 32-bit unsigned integer and the array bitmap_auxiliary_array through a mapping formula. The elements in the array represent the position of the lowest bit set to 1 in the 32-bit unsigned integer. Substitute the unsigned integer into the mapping formula to obtain a result value of 0-31. Use this value as an index to obtain the corresponding element from the array. The element is the position of the lowest bit set to 1 in the 32-bit unsigned integer. If there is no bit set to 1 in the first half of the bitmap, continue to search for the lowest bit set to 1 in the second half according to the above method. Then the bitmap is updated according to the found index position, the position is set to 0, indicating that the memory block has been allocated, and then the corresponding memory block is allocated.
[0050] Algorithm 3: Available memory block search algorithm
[0051]
[0052] Instructions attached Figure 5 The figure is a flow chart of the allocation interface of the memory allocator that adopts the optimized memory block wear leveling strategy.
[0053] The following is an explanation of the various interfaces for memory release:
[0054] (1) hpnmalloc(size): The program issues a memory request and calls the memory allocation interface hpnmalloc, which accepts a parameter indicating the size of the memory requested.
[0055] (2) judge_block_category(size): determines whether the memory block to be operated is a small memory block, a large memory block, or an extra-large memory block.
[0056] (3) check_localcache(size): If it is a small memory block, call this function to check whether there is a corresponding free small memory block in the thread cache.
[0057] (4) acquire_Span_from_localcache(size): Allocates the corresponding free small memory block from the thread cache according to the requested memory size.
[0058] (5) cal_AP(): Calculates the priority value based on the parameters of the memory pool.
[0059] (6) select_highest_pool(): Sorts the memory pools by priority value from large to small, and searches from the head until an available memory pool is found.
[0060] (7) update_threshold(): Updates the thread's wear threshold based on the Span requested from the memory pool by the thread cache.
[0061] (8) Span_clock_allocate(Span, size): Allocate small memory blocks in Span using the clock allocation algorithm.
[0062] (9) large_allocate(memorypool, size): finds a suitable memory block in the memory pool according to the size of the requested memory and allocates it.
[0063] (10) huge_allocate(size): directly calls the mmap system call to allocate a very large memory block.
[0064] (11)update_AP(memorypool): Updates the priority value of the corresponding memory pool.
[0065] Instructions attached Figure 6 It is the memory release interface flow chart.
[0066] The following will explain the various interfaces for memory release.
[0067] (1) hpnfree(addr): The program issues a memory release request and calls the memory allocation interface hpnfree. The interface accepts a parameter indicating the starting address of the memory block to be released.
[0068] (2) extra_Span_head(addr): Get the Span block header based on the address
[0069] (3) judge_block_category(size): determines whether the memory block to be operated is a small memory block, a large memory block, or an extra-large memory block.
[0070] (4)small_block_free(Span,memorypool): Enters the small memory block release process.
[0071] (5)large_block_free(Span,memorypool): Enters the large memory block release process.
[0072] (6) huge_block_free(Span, memorypool): Enter the huge memory block release process
[0073] (7)should_back_to_memorypool(Span): Checks whether the small memory block meets the conditions for returning to the memory pool (checks whether the wear value of the Span has reached the wear threshold of the thread cache and all memory blocks have been released. If so, the memory block is returned to the corresponding memorypool. If not, the small memory block is returned to the Span).
[0074] (8)should_update_Max_Span_WearCount(Span,wear_count): Determines whether the Max_WearCount value in the memory pool needs to be updated (when the wear value of Span is greater than Max_WearCount, Max_WearCount needs to be updated).
[0075] (9)update_Max_Span_WearCount(memorypool,span_wearcount): This function is used to update the value of Max_Span_WearCount and reset the max_wear_Span_ptr pointer in lb_free_list.
[0076] (10)back_to_Span(addr,Span): Returns a small memory block to Span.
[0077] (11)bcak_to_memorypool(Span,memorypool): returns Span to the memory pool.
[0078] (12)back_to_OS(addr): Returns a large memory block to the operating system.
[0079] Algorithm evaluation:
[0080] For an NVM-oriented memory allocator, both operating performance and wear optimization effect are crucial evaluation indicators, so this section will experimentally verify the present invention based on these two indicators. For the wear optimization effect, the wear difference control algorithm and the memory block clock allocation algorithm together constitute the wear difference control and clock allocation strategy. This section first evaluates the effect of this strategy, and then for the operating performance, the experiment selects Wamalloc and NVMalloc, two NVM-oriented memory allocators, to compare with the present invention.
[0081] Experimental environment:
[0082] The experimental environment is shown in Table 3.1. The present invention implements the memory allocator HPNMalloc in the Linux operating system and conducts relevant experiments.
[0083] Table 1 Experimental environment
[0084]
[0085] Currently, most NVMs are still in the research stage. The only commercially available Optane non-volatile memory is expensive due to its large memory capacity. Therefore, the paper uses the method of simulating NVM in the experiment, simulating the 7GB DRAM as non-volatile memory. Since version 4.0, the Linux kernel has supported the use of DRAM to simulate persistent memory devices. The following are the specific simulation steps.
[0086] The distribution of the system's physical memory is obtained through dmesg|grup e820. On different architectures, the commands for obtaining the distribution of the system's physical memory are different. In the x86 architecture, e820 is a hardware that can detect the distribution of physical memory. A memory distribution table is retained in e820, and the distribution of physical memory can be obtained through the table. There are many types of physical memory obtained through the table, including usable memory, reserved memory, etc., among which usable memory represents that the memory segment can be used. The present invention mainly uses it to simulate non-volatile memory.
[0087] According to your needs, determine the non-volatile memory address range to be simulated in the usable memory.
[0088] Configure the Ubuntu boot file (grub file), retain the physical memory allocated in the previous step in the system, and then update the boot file and restart the host to make the configuration take effect.
[0089] After rebooting, you can see the non-volatile memory device pmem emulated by DRAM in the / dev directory.
[0090] Finally, create and mount a DAX-enabled file system for the simulated persistent device. You can then use mmap file mapping to map non-volatile memory into the user's virtual address space and perform byte-wise addressing, reading, and writing.
[0091] The present invention mainly divides the non-volatile memory into 4 segments and simulates 4 non-volatile devices. Since they are all simulated by DRAM and cannot reflect heterogeneous characteristics, the present invention assigns different parameters to them through software simulation. The specific parameters of the 4 non-volatile devices are shown in Table 2.
[0092] Table 2 Non-volatile device parameter information
[0093]
[0094] For the acquisition of memory writes, the present invention uses a dynamic binary plugging tool pin developed by Intel, which can be used to dynamically plug executable programs at runtime to analyze the program's running information. It supports multiple platforms such as Linux, macOS, Windows, and instruction architectures such as IA-32 and Intel (R) 64. Generally speaking, to complete the analysis of the target program through plugging, it is necessary to understand the location of the plugging and the inserted code, that is, the plugging part and the analysis code part. These two parts are integrated into a class of executable programs in Pin, that is, Pintool. Pintool is a tool written by the user to call the functions in the Pin library according to the analysis requirements to complete the plugging analysis requirements. Pin completes the analysis of the target program by calling and executing Pintool. The paper uses the memory call tracking tool pinatrace.so provided by the pin tool to track the program's read and write memory.
[0095] Experimental Evaluation
[0096] 1. Evaluation of wear difference control and clock distribution strategy effects:
[0097] This section mainly evaluates the effect of the memory block wear leveling algorithm. The test set is shown in Table 3. The experiment selected NVMalloc, Wamalloc and HPNMalloc (named HPNMalloc1 in this experiment) which adopts a simple memory block wear leveling strategy as experimental objects. All three are NVM-oriented memory allocators and all adopt the memory block wear leveling algorithm. The test set is shown in Table 3.
[0098] Table 3 Test set information
[0099]
[0100] The experiment uses the pin tool to obtain the write status of the basic storage unit in the NVM, and uses the average number of writes to the basic storage unit as one of the criteria for measuring the wear effect. First, count the number of writes to each basic unit, then add up these write times and divide them by the number of basic units to get the average number of writes to each basic unit. Figure 7 This is a comparison of the average number of writes to the basic storage units of the four memory allocators. The horizontal axis of the figure represents the number of memory block writes, and the vertical axis represents the average number of writes to the basic unit under this number of writes.
[0101] From the instruction manual Figure 7 It can be seen that since the four memory allocators have adopted certain wear optimization strategies, their average number of writes does not increase significantly with the increase in the number of allocations. In addition, for small memory allocations, for memory blocks in the range of [0,512] bytes, the average number of writes of HPNMalloc is significantly lower than that of the other three memory allocators, and for mixed memory block allocations, the average number of writes of HPNMalloc is also significantly lower than that of the other three memory allocators. The following are the experimental results:
[0102] Under the condition of randomly allocating [0,128] bytes, HPNMalloc reduces the average number of writes by 37.7% compared to HPNMalloc1, 38.7% compared to Wamalloc, and 44.2% compared to NVMMalloc.
[0103] Under the condition of random allocation of [0,256] bytes, HPNMalloc reduces the average number of writes by 23% compared to HPNMalloc1, by 23.4% compared to Wamalloc, and by 34.2% compared to NVMMalloc.
[0104] Under the condition of random allocation of [0,512] bytes, HPNMalloc reduces the average number of writes by 11.1% compared to HPNMalloc1, by 14.3% compared to Wamalloc, and by 24.4% compared to NVMMalloc.
[0105] Under the condition of randomly allocating [0,1024] bytes, HPNMalloc reduces the average number of writes by 2.3% compared to HPNMalloc1, 8.3% compared to Wamalloc, and 15.7% compared to NVMMalloc.
[0106] Under the condition of randomly allocating [0,4096] bytes, HPNMalloc increases the average number of writes by 5.1% compared to HPNMalloc1, reduces it by 0.7% compared to Wamalloc, and reduces it by 4.8% compared to NVMMalloc.
[0107] Under the condition of randomly allocating [0,10240] bytes, HPNMalloc reduces the average number of writes by 44.4% compared to HPNMalloc1, 47.2% compared to Wamalloc, and 49.1% compared to NVMMalloc.
[0108] From the instruction manual Figure 7 The following conclusions can be drawn: for small memory blocks, the smaller the allocated memory block, the more obvious the wear optimization effect of the wear leveling strategy. Due to the clock allocation algorithm, a page size is fixed, so the smaller the allocated memory block, the more small memory blocks can be allocated to the page, so when a small memory block is released, it will take longer for it to be allocated next time. For mixed memory allocation, due to the use of the wear difference control algorithm, its effect is also significantly greater than other memory allocators.
[0109] This experiment uses variance to measure the balance of the number of writes. The larger the variance, the greater the dispersion of the data points relative to the mean, indicating that the number of writes between the basic storage units is more unbalanced, and vice versa, indicating that the number of writes between the basic storage units is more balanced. Figure 8 The wear variance of the basic unit number of four memory allocators is compared. From the experimental results, it can be seen that the variance of HPNMalloc is generally smaller than that of HPNMalloc1, Wamalloc and NVMalloc, which indicates that its wear leveling effect is better.
[0110] 2. Operational performance evaluation:
[0111] This section mainly evaluates the performance of HPNMalloc and compares it with Wamalloc and NVMalloc. The experiment uses test set 5 and test set 6, which are performed in single thread and multi-thread respectively. Fig. 9 The following is the experimental result of a single thread. The horizontal axis represents the number of allocations, and the vertical axis represents the average time spent on each allocation. The experiment shows that under single thread conditions, when randomly allocating memory blocks in the range of [0,4096] bytes, the running performance of HPNMalloc is 9% lower than Wamalloc and 8.5% lower than NVMalloc. When randomly allocating memory blocks in the range of [0,10240] bytes, the running performance of HPNmalloc is 5.2% higher than that of HPNMalloc1, 9% lower than Wamalloc, and 9.1% lower than NVMalloc.
[0112] Instructions attached Fig.10The figure shows the experimental results under multi-threaded conditions. The experiment mainly tests small memory block allocation and mixed memory block allocation (small memory blocks and large memory blocks exist). The experiment selects data sets 5 and 6 for the experiment, and sets the concurrency to 10 threads. The horizontal left is the number of allocations, and the vertical axis is the average time spent on each allocation.
[0113] Experiments show that under the condition of 10 threads, when randomly allocating memory blocks in the range of [0,4096] bytes, the running performance of HPNMalloc is 7.8% lower than Wamalloc and 49.7% higher than NVMalloc. When randomly allocating memory blocks in the range of [0,10240] bytes, the running performance of HPNmalloc is 8.4% lower than Wamalloc and 60.2% higher than NVMalloc. In summary, under single-thread conditions, HPNMalloc is slightly worse than Wamalloc and NVMalloc. Under multi-thread conditions, the running performance of HPNMalloc is better than NVMalloc, but slightly worse than Wamalloc.
[0114] The above description is only a detailed description of the preferred embodiments and principles of the present invention. For ordinary technicians in this field, according to the ideas provided by the present invention, there will be changes in the specific implementation methods, and these changes should also be regarded as the protection scope of the present invention.
Claims
1. A memory block wear leveling strategy optimization method, characterized in that: The following steps are involved: S1. Divide the NVM memory block into a large memory block and a small memory block. The range of the small memory block is less than or equal to 4KB, and the range of the large memory block is greater than 4KB and less than or equal to 1MB. S2. Add a field Span_wear_count to the block header structure of the interval Span to record the wear value of the Span corresponding to the large memory block and the small memory block; S3. In the NVM memory pool, add the Max_Span_WearCount variable to record the wear value of the most severely worn Span in the memory pool; add the max_wear_Span_ptr pointer to point to the first node whose wear value is equal to Max_Span_WearCount in the linked list composed of multiple Span nodes; S4. In the thread cache, set the wear value threshold Wear_Threshold so that the wear values of all spans in the thread cache do not exceed this threshold; S5. For small memory blocks, a clock distribution algorithm is used for uniform distribution.
2. The memory block wear leveling strategy optimization method according to claim 1, characterized in that: The implementation process of the field Span_wear_count is as follows: for a large memory block, the value of the field is increased by 1 each time it is allocated; for a small memory block, the value of the field is increased by 1 each time a search is performed in the Span.
3. The memory block wear leveling strategy optimization method according to claim 1, characterized in that: The step S3 also includes that when allocating memory, allocating memory starts from the node whose wear value at the head of the linked list is less than Max_Span_WearCount; if the wear values of all nodes in the linked list are less than Max_Span_WearCount, max_wear_Span_ptr is set to NULL.
4. The memory block wear leveling strategy optimization method according to claim 3, characterized in that: The value of Max_Span_WearCount changes dynamically. When the Span is returned from the thread cache to the memory pool, the wear value of the Span is compared with the value of Max_Span_WearCount. If they are greater, the Max_Span_WearCount and max_wear_Span_ptr pointers are updated.
5. The memory block wear leveling strategy optimization method according to claim 4, characterized in that: The specific implementation process of step S4 is as follows: when the wear value of a certain Span reaches the wear value threshold, it is prohibited to continue to allocate memory; an unavailable state unavailable is added to the Span in the thread cache, and the unallocated small memory blocks are managed through the unavailable_array array; each linked list node in the unavailable_array has a fixed one-to-one correspondence with the size of the small memory block.
6. The memory block wear leveling strategy optimization method according to claim 1, characterized in that: The specific implementation of the clock distribution algorithm includes the following processes: S5.
1. Modify the block header structure of Span, change the original available free start position available_free_start field to a bitmap field, and delete the small memory block header node small_block_header_node field; add the current pointer cur_pos pointing to the small memory block to be allocated next time and the end position last_pos field pointing to the bitmap; S5.
2. When allocating a memory block, search for the first available memory block clockwise starting from cur_pos. If no available memory block is found when reaching last_pos, it means that one round of allocation is over, Span_wear_count is increased and the search starts again.
7. The memory block wear leveling strategy optimization method according to claim 6, characterized in that: Each bit in the bitmap represents the allocation status of the corresponding small memory block, 0 represents being in use, and 1 represents being free.
