page fault和数据访问方式对性能的影响

在某种极端的情况下
缺页异常page fault会严重影响进程的性能

假设:
页大小为128bytes
一个进程用到了128个页
内存只能给这个程序分配127个页的内存
我们编程时其中有一段访问了一个128*128大小的数组

代码是这样的:

for i = 1 to 128:
    for j = 1 to 128:
        A[j,i] = 0;

由于数组在一般内存中是按行存储的,而页是连续的一段内存
即A[1,1] A[1,2] A[1,3] …. 算是在一个页内

由于访问数组的方式是A[j,i]
由于i循环在外,数据访问顺序是:
A[1,1] A[2,1] A[3,1] … 其中每个数据都保存在不同的页内

由于内存只分配了127个页,少了一个页
第一遍外循环i = 1肯定是page fault
产生了page fault就要把数据复制到内存,更新页表,前127个还好,有空余的内存能分配。可是到了第128个,空间不够了,一般策略是停留时间最长的覆盖掉,于是第128页(包含数据A[128,1] A[128,2] … A[128,n]) 覆盖掉了第1页(包含数据A[1,1] A[1,2] … A[1,n])
第二遍外循环 i = 2 开始,于是开始访问数据 A[1,2] A[2,2] A[3,2] … A[128,2] 由于这还是分别属于不同页的数据,A[1,2] 是第一个页的数据(而第一个页刚刚被128页覆盖),于是覆盖掉第2页。然后轮到A[2,2],自己所属的第2个页刚刚被覆盖,只能去欺负待的时间最长的页3。
以此类推其实每次都会产生page fault,总共128*128次。

如果使用A[i,j]来访问数据。
那么一次循环内数据访问顺序是A[1,1] A[1,2] A[1,3] … A[1,128] 这都是在一个页上的数据,因此一次循环内只会一次page fault。只要第一次page fault把数据赋值到内存,之后的127次访问都是没问题的。由于外循环是128次,所以总共有128次page fault。

结论

page fault开销还是很大的。

如果内存容量有限,不是总是能给进程分配足够多内存,而且page fault的算法不”聪明”,那么这时候数据访问的顺序是很重要的。

    原文作者:Htea
    原文地址: https://www.jianshu.com/p/84afd37e350f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞