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

C 生成漂亮和/或系统密集度较低的测量点,c,performance,performance-testing,strace,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=500

我使用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;
}
最后,我可以马上看出:

 0.000110 open("/", O_RDONLY)       = 3
 0.203487 open("/", O_RDONLY)       = 4
 0.202225 open("/", O_RDONLY)       = 5
回到我设置的三个测量点

我希望能够调整代码中的测量点行,这样当我运行strace时,我可以像现在一样找到我的测量点,但系统的操作强度较低。除了文件调用之外,我没有从strace中看到任何与我的程序相关的东西

我在想,如果C中有一个内置的MeasureMe函数,我可以用它来代替代码中的测量点行,那么strace可以输出:

 0.000110 MeasureMe called in code
 0.203487 MeasureMe called in code
 0.202225 MeasureMe called in code
我有没有办法和斯特拉斯谈谈

我之所以询问strace而不是gdb,是因为我使用它来调试对apache服务器的请求,就像本视频中的人那样,我将能够看到apache模块的运行:


你知道我怎么解决这个问题吗?还是我必须继续尝试打开不存在的文件失败?

我收集您当前使用的是
打开(“/”,O_RDONLY)
[或
打开(“/I_不存在”,O_RDONLY)
]作为“跟踪点”。不幸的是,由于您使用的是
strace
,因此只能使用系统调用。但是,有一种方法可以达到你想要的效果


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

  • 任何不会损害任何东西的唯一系统调用
  • 易于与真实代码区分[甚至可能返回错误的代码,如打开文件或使用
    访问检查是否存在
    ]
  • 最小的开销/最快的执行速度

  • 事实上,坏的fildes上的dup能很好地填补账单:

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

    你想要多少就有多少。实际参数成为“跟踪点编号”:

    输出将如下所示:

         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
    
    现在,我将编写一个
    perl
    python
    脚本来读取源文件,提取给定跟踪点的注释,并将它们附加到
    strace
    输出文件中的匹配行:

         0.000044 TRACEPOINT(1) initialization phase
         0.000022 TRACEPOINT(2) execution phase
         0.000019 TRACEPOINT(3) cleanup/shutdown
    

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

  • 跟踪时间戳,并将一个跟踪点和上一个跟踪点之间的时间差附加到跟踪行
  • 将文件名和行号信息添加到跟踪点行
  • 跟踪给定跟踪点被命中的次数[类似于
    gdb
    和断点]
  • 生成与跟踪点相关的摘要报告

  • 通过使用
    open(…,O_PATH)
    ,您可能可以降低
    open()系统调用的成本。
    
    TRACEPOINT(1);  // initialization phase
    ...
    TRACEPOINT(2);  // execution phase
    ...
    TRACEPOINT(3);  // cleanup/shutdown
    
         0.000044 TRACEPOINT(1) initialization phase
         0.000022 TRACEPOINT(2) execution phase
         0.000019 TRACEPOINT(3) cleanup/shutdown