代码之家  ›  专栏  ›  技术社区  ›  Sniggerfardimungus

当从磁盘中出现页面故障时,哪个(OS X)dtrace探测器触发?

  •  3
  • Sniggerfardimungus  · 技术社区  · 16 年前

    我正在写一个关于页面错误的文档,并尝试使用一些具体的数字,因此我编写了一个简单的程序,它读取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);
    }
    

    所以是的,它会读取整个文件。问题是我需要DTrace探针,在这个过程中(12M/8K),它将发射1536次。即使我计算了所有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);
    }
    

    这个版本的运行时间要长得多(42秒是实时的,其中10秒是用户,其余的是系统时间页错误,我猜),但仍然会产生我预期的五分之一的错误。

    奇怪的是,时间增长并不是由于循环开销和强制转换(char到int)造成的,仅执行这些操作的代码版本需要0.07秒。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Nikolai Fetissov    16 年前

    这不是一个直接的答案,但您似乎把磁盘读取和页面错误等同起来了。它们不一定是相同的。在您的代码中,您正在将数据从一个文件读取到一个小的用户内存块中,因此I/O系统可以以任何它认为合适的方式和大小将文件读取到buffer/vm缓存中。我可能错了,我不知道达尔文是怎么做到的。

    我认为更可靠的测试应该是 mmap(2) 整个文件进入进程内存,然后去触摸每个页面就是那个空间。

        2
  •  1
  •   Mike Harsch    15 年前

    我最近在同一个小洞里。我目前没有可用的DTrace脚本或测试程序,但我将向您提供以下建议:

    1.)使用Amit Singh开发的OSX内部构件,并阅读第8.3节“虚拟内存”(这将使您进入选择dtrace探针的正确参考框架)。

    2.)了解Brendan Gregg/Jim Mauro的Solaris性能和工具。阅读虚拟内存部分,并密切关注使用vminfo提供程序的dtrace脚本示例。

    3.)OSX绝对是从文件系统预取大的页面块,并且您的测试程序正在进行这种优化(因为您是按顺序读取的)。有趣的是,对于Solaris,情况并非如此。尝试随机访问大数组以击败预取。

        3
  •  0
  •   FrankH.    15 年前

    假设操作系统将在作为单独操作被触摸的每个页面中出错(因此,如果触摸n个页面,您将看到dtrace probe fire n次),这是有缺陷的;大多数un*xes将执行某种预读或预错,并且您不太可能获得完全相同的调用数。因为你有页面。即使直接使用mmap(),也是如此。

    准确的比率也可能取决于文件系统,因为readahead和page集群实现以及阈值对于所有实现都不太可能相同。

    如果直接使用mmap,然后应用madvise(madv-dontned)或类似工具和/或使用msync(ms-invalidate)清除整个范围,则可能会强制使用每页错误策略。

    推荐文章