产生漂亮和/或系统密集度较低的测量点

时间:2016-02-20 21:16:34

标签: c performance performance-testing strace

我使用C和我制作apache模块,我使用strace作为调试时间的主要工具。这是我扔在一起的代码。如果变量名称不符合标准,我表示歉意。

#include <stdio.h>
int main(){
    long ct2,ct; //counters
    int a=0; //dummy value
    FILE *f0=fopen("/","r"); //measuring point
    ct2=10;
    while (--ct2>0){
      ct=5000000;
      while (--ct>0){
        if (!!a){
          printf("%d",a);
        }
      }
    }
    FILE *f=fopen("/","r");  //measuring point
    ct2=10;
    while (--ct2>0){
      ct=5000000;
      while (--ct>0){
        if (a){
          printf("%d",a);
        }
      }
    }
    FILE *f2=fopen("/","r");  //measuring point
    return 0;
}

此代码可以编译。然后我通过strace运行它(通过键入终端:strace -r -ttt ./a.out),我看到了:

 0.000000 execve("./a.out", ["./a.out"], [/* 47 vars */]) = 0
 0.000315 brk(0)                    = 0x804a000
 0.000124 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
 0.000144 open("/etc/ld.so.cache", O_RDONLY) = 3
 0.000116 fstat64(3, {st_mode=S_IFREG|0644, st_size=139721, ...}) = 0
 0.000138 mmap2(NULL, 139721, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7ece000
 0.000114 close(3)                  = 0
 0.000109 open("/lib/libc.so.6", O_RDONLY) = 3
 0.000113 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360d\1"..., 512) = 512
 0.000130 fstat64(3, {st_mode=S_IFREG|0755, st_size=1575187, ...}) = 0
 0.000131 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ecd000
 0.000122 mmap2(NULL, 1357360, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7d81000
 0.000119 mmap2(0xb7ec7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x146) = 0xb7ec7000
 0.000146 mmap2(0xb7eca000, 9776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7eca000
 0.000139 close(3)                  = 0
 0.000112 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d80000
 0.000119 set_thread_area({entry_number:-1 -> 6, base_addr:0xb7d806c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
 0.000217 mprotect(0xb7ec7000, 4096, PROT_READ) = 0
 0.000108 munmap(0xb7ece000, 139721) = 0
 0.000174 brk(0)                    = 0x804a000
 0.000099 brk(0x806b000)            = 0x806b000
 0.000110 open("/", O_RDONLY)       = 3
 0.203487 open("/", O_RDONLY)       = 4
 0.202225 open("/", O_RDONLY)       = 5
 0.000133 exit_group(0)             = ?

我最后可以告诉你:

 0.000110 open("/", O_RDONLY)       = 3
 0.203487 open("/", O_RDONLY)       = 4
 0.202225 open("/", O_RDONLY)       = 5

返回我设置的三个测量点。

我希望能够在我的代码中调整测量点线,这样当我运行strace时,我可以像现在一样找到我的测量点,但系统的操作次数较少。除了文件调用之外,我没有看到与我的程序相关的任何其他内容。

我想也许在C中有一个内置的MeasureMe函数可以用来代替代码中的测量点线,然后strace可以输出:

 0.000110 MeasureMe called in code
 0.203487 MeasureMe called in code
 0.202225 MeasureMe called in code

有什么方法可以用Strace来解决这个问题吗?

我之所以要问strace而不是gdb是因为我用它来调试请求到我的apache服务器,就像这个视频中的人那样,我将能够看到apache模块在运行:< / p>

https://www.youtube.com/watch?v=eF-p--AH37E

知道如何解决这个问题吗?或者我是否必须继续尝试打开不存在的文件?

1 个答案:

答案 0 :(得分:2)

我收集您当前使用的是open("/",O_RDONLY) [或open("/i_do_not_exist",O_RDONLY)]的“跟踪点”。不幸的是,因为你正在使用strace,所以你被限制使用系统调用。但是,一种实现所需效果的方法。

您在源代码中的各个点手动插入的跟踪点需要/想要的是:

  1. 任何不会伤害任何内容的唯一系统调用
  2. 很容易与真实代码[甚至可能返回错误的代码区分开来,例如打开文件或检查存在access]
  3. 最小开销/最快执行
  4. 实际上,dup关于一个糟糕的fildes很好地填补了这个账单:

    dup(-10000);
    

    它将返回EBADF。它很容易被区分为跟踪点,因为大多数真正的dup调用“不好”将是dup(-1)

    您可以根据需要添加尽可能多的这些内容。实际参数成为“跟踪点编号”:

    dup(-10001);  // tracepoint 1
    ...
    dup(-10002);  // tracepoint 2
    ...
    dup(-10003);  // tracepoint 3
    

    输出如下:

         0.000044 dup(-10001)               = -1 EBADF (Bad file descriptor)
         0.000022 dup(-10002)               = -1 EBADF (Bad file descriptor)
         0.000019 dup(-10003)               = -1 EBADF (Bad file descriptor)
    

    我通常将其封装在一个宏中:

    #ifdef DEBUG
    #define TRACEPOINT(_tno)        tracepoint(_tno)
    #else
    #define TRACEPOINT(_tno)        /**/
    #endif
    
    void
    tracepoint(int tno)
    {
        dup(-10000 - tno);
    }
    

    然后,我添加了类似的内容:

    TRACEPOINT(1);  // initialization phase
    ...
    TRACEPOINT(2);  // execution phase
    ...
    TRACEPOINT(3);  // cleanup/shutdown
    

    现在,我将编写一个perlpython脚本来读取源文件,提取给定跟踪点的注释,并将它们附加到{{1}中的匹配行输出文件:

    strace

    更复杂的后处理脚本版本可以执行各种操作:

    1. 跟踪时间戳并将一个跟踪点与前一个跟踪点之间的时间差追加到跟踪线
    2. 将文件名和行号信息添加到跟踪点行
    3. 跟踪命中跟踪点的次数[类似于 0.000044 TRACEPOINT(1) initialization phase 0.000022 TRACEPOINT(2) execution phase 0.000019 TRACEPOINT(3) cleanup/shutdown 和断点]
    4. 生成与跟踪点相关的摘要报告