为何刷新缓存后访问mmap内存未触发Page Fault?
为何填充内存映射文件后清空缓存再访问不会触发Page Fault?
我编写了一段用于触发Page Fault的Python代码,流程如下:
- 创建临时文件并通过
np.memmap()API进行内存映射 - 填充内存
- 刷新内存,执行
sudo sh -c "sync; echo 3 > /proc/sys/vm/drop_caches"并等待5秒 - 通过索引访问内存
我预期在最后一步访问内存时会触发Page Fault,用perf trace -F maj --no-syscalls命令监控,但实际并未出现。
完整代码如下:
import mmap import os from time import sleep import timeit import torch import torch.nn as nn from torch.optim import Optimizer import torch.nn.functional as F import numpy as np from collections import namedtuple import random import math from time import time #ref: np.memmap usage from tempfile import mkdtemp import os.path as path filename = path.join(mkdtemp(), 'newfile.dat') # 创建临时文件在/tmp/tmp*/newfile.dat data_size = 10240*10240 data = np.arange(data_size, dtype='float32') data.resize((10240,10240)) # step i) 创建内存映射 fp = np.memmap(filename, dtype='float32', mode = 'w+', shape=(10240,10240)) # step ii) 填充内存 fp[:] = data[:] # 这一步会触发针对/tmp/tmp*/newfile.dat的Page Fault # step iii) 刷新并清空缓存 fp.flush() os.system('sudo sh -c "sync; echo 3 > /proc/sys/vm/drop_caches"') sleep(5) # step iv) 访问内存 ''' 原本预期下面四次访问会触发4次针对/tmp/tmp*/newfile.dat的Page Fault 但如果先执行了fp[:] = data[:],即使清空缓存后访问,也不会触发缺页 ''' print(fp[0]) print(fp[100]) print(fp[1000]) print(fp[10000])
我做了两组对比测试:
- 跳过步骤ii的内存填充操作,直接访问数组
fp时会触发Page Fault - 跳过步骤ii和iii,直接执行步骤iv也会触发Page Fault
对应的perf输出如下:
14353.230 ( 0.000 ms): sudo/63776 majfault [0x7fc101575004] => /tmp/tmpz00lweix/newfile.dat@0x4 (d.) 14355.719 ( 0.000 ms): sudo/63776 majfault [0x7fc10195d004] => /tmp/tmpz00lweix/newfile.dat@0x3e8004 (d.) 14357.331 ( 0.000 ms): sudo/63776 majfault [0x7fc103c85004] => /tmp/tmpz00lweix/newfile.dat@0x2710004 (d.) 14357.658 ( 0.000 ms): sudo/63776 majfault [0x7fc119c15004] => /tmp/tmpz00lweix/newfile.dat@0x186a0004 (d.)
请问我遗漏了什么环节?
内容的提问来源于stack exchange,提问作者user19133452
相关产品推荐
相关产品推荐

