## 2 Materials and Methods
### Memory Allocation for Non-Real-Time Tasks
#### 2.2.7. Memory Compression Factor  
In order to further optimize memory allocation decisions in the non-real-time zone, we introduce a parameter called the \"memory compression factor\" to adjust the decision value. The memory compression factor is an attribute of memory blocks and comes into effect when computing the value of a particular allocation decision. The value generated by allocating a certain free memory block will be multiplied by its memory compression factor. With the introduction of the memory compression factor, the formula for computing the allocation value changes as follows:  
\[Value^{j}_{i}= \begin{cases}0&\text{if }\mathit{mSize}_{i}<\mathit{Req}_{j},\\ \dfrac{MaxMem\cdot MCF_{i}}{mSize_{i}-\mathit{ReqSize}_{j}+1}&\text{if }\mathit{mSize}_{i}\geq \mathit{ReqSize}_{j}.\end{cases}  \tag{8}\]  
When a new memory block is created, its memory compression factor is set to the default value. Each time a memory block participates in memory allocation, the value of its memory compression factor is shifted to the right by one bit. Each time a memory block participates in memory compression, its memory compression factor is reset. If a memory block is divided, the newly generated blocks inherit the memory compression factor of the original block. The introduction of the memory compression factor aims to increase the chances of memory blocks participating in memory compression, thereby reducing external fragmentation and improving memory utilization. The performance of allocation strategies using different memory compression factors for a set of non-real-time tasks is shown in Figure 5. In this paper, all figures related to data were plotted using the Matplotlib library implemented in Python. It can be observed that, compared to not introducing a memory compression factor (i.e., a memory compression factor of 1), introducing a memory compression factor within a certain range has a significant effect on reducing the average fragmentation rate and reducing the required execution time. When the memory compression factor is 5, the shortest execution time for processing the task set is achieved, which is a 6.2% improvement compared to not introducing the factor. From Figure 5, it can be seen that, as the memory compression factor increases, the average fragmentation rate fluctuates less within a certain range, and the execution time for processing the task set decreases significantly at the beginning but increases significantly when the memory compression factor exceeds 25. Experimental results show that low average fragmentation rate does not always mean high processing efficiency. It can be observed that, under similar average memory fragmentation rates, there are still significant differences in the required execution time for processing the task set with different memory compression factors. To explain this phenomenon, we sampled the memory utilization rate at intervals of every 100 allocations using the same task set. We observed the sampling results of four memory compression factors with similar average memory fragmentation rates (5 (18.4%), 9 (18.7%), 22 (17.7%), and 27 (17.4%)), as shown in Figure 6.  
It can be observed that, when the memory compression factor is 5, the fluctuation of memory utilization rate is smaller at different time intervals. In the sampling results, the memory utilization rate is mainly concentrated between 10% and 25%, and the probability of sampling points beyond this range is 21%. However, under other memory compression factors, the fluctuation in memory utilization rate increases significantly. When the memory compression factors are 9, 22, and 27, the probabilities of sampling points beyond this range are 41%, 44%, and 40%, respectively. Figure 5: Processing time of task set and average memory fragmentation rate under different memory compression factors. In edge PLCs, the time it takes for computing tasks to occupy allocated memory space is relatively long.