我正在撰写一篇关于页面错误的文档,并且正在尝试使用一些具体数字,因此我编写了一个简单的程序,读取12 * 1024 * 1024字节的数据。易:
int main()
{
FILE*in = fopen("data.bin", "rb");
int i;
int total=0;
for(i=0; i<1024*1024*12; i++)
total += fgetc(in);
printf("%d\n", total);
}
是的,它会通过并读取整个文件。问题是我需要在此过程中触发1536次的dtrace探测器(12M / 8k)。即使我计算了所有的fbt:mach_kernel:vm_fault *:探针和所有的vminfo :::探针,我也没有达到500,所以我知道我找不到合适的探针。
任何人都知道在哪里可以找到当磁盘出现故障时触发的dtrace探测器?
更新:
关于stdio函数中存在一些智能预取的问题,我尝试了以下内容:
int main()
{
int in = open("data.bin", O_RDONLY | O_NONBLOCK);
int i;
int total=0;
char buf[128];
for(i=0; i<1024*1024*12; i++)
{
read(in, buf, 1);
total += buf[0];
}
printf("%d\n", total);
}
这个版本需要更长时间才能运行(42s实时,其中10s是用户,剩下的是系统时间 - 页面错误,我猜)但仍然产生的故障数量是我预期的五分之一。
对于好奇,时间增加不是由于循环开销和转换(char到int。)执行这些操作的代码版本需要.07秒。
答案 0 :(得分:1)
不是直接的答案,但似乎是在等同磁盘读取和页面错误。它们不一定相同。在您的代码中,您正在将文件中的数据读取到一个小的用户内存块中,因此I / O系统可以以适合的任何方式和大小将文件读入缓冲区/ VM缓存。我可能在这里错了,我不知道达尔文是如何做到的。
我认为更可靠的测试是将mmap(2)
整个文件放入进程内存然后触摸每个页面就是那个空间。
答案 1 :(得分:1)
我最近和同样的rathole一样。我刚才没有可用的DTrace脚本或测试程序,但我会给你以下建议:
1。)获取Amit Singh的OS X Internals并阅读有关虚拟内存的第8.3节(这将使您选择正确的参考框架以选择DTrace探针)。
2。)获取Brendan Gregg / Jim Mauro的Solaris性能和工具。阅读有关虚拟内存的部分,并密切关注使用vminfo提供程序的示例DTrace脚本。
3。)OS X肯定会从文件系统中预取大块页面,并且您的测试程序正在进行此优化(因为您正在按顺序阅读)。有趣的是,Solaris不是这种情况。尝试随机访问大数组以取消预取。
答案 2 :(得分:0)
假设操作系统会在作为单独操作被触摸的每个页面中出错(因此,如果触摸N页,您将看到DTrace探测器触发N次)是有缺陷的;大多数UN * Xes会执行某种预读或预先故障,你不可能得到与你有页面完全相同的调用次数。即使您直接使用mmap()也是如此。
确切的比例也可能取决于文件系统,因为预读和页面聚类实现和阈值对于所有这些都不太可能相同。
如果直接使用mmap然后应用madvise(MADV_DONTNEED)或类似的和/或使用msync(MS_INVALIDATE)清除整个范围,则可能强制执行每页错误策略。