为什么C ++和strace不同意open()系统调用的时间长短?

时间:2014-02-27 22:35:26

标签: c++ linux profiling strace

我有一个打开大量文件的程序。我正在计算C ++循环的执行时间,它实际上只是使用C ++计时器和strace来打开和关闭文件。奇怪的是,系统时间和C ++记录的时间(彼此一致)比数字系统调用花费的时间大几个数量级。怎么会这样?我把源和输出放在下面。

这一切都是因为我发现我的应用程序花费了不合理的时间来打开文件。为了帮助我解决问题,我编写了以下测试代码(供参考文件“files.csv”只是一个每行一个文件路径的列表):

#include <stdio.h>
#include...

using namespace std;

int main(){
  timespec start, end;
  ifstream fin("files.csv");
  string line;
  vector<string> files;
  while(fin >> line){
    files.push_back(line);
  }
  fin.close();

  clock_gettime(CLOCK_MONOTONIC, &start);
  for(int i=0; i<500; i++){
    size_t filedesc = open(files[i].c_str(), O_RDONLY);
    if(filedesc < 0) printf("error in open");
    if(close(filedesc)<0) printf("error in close");
  }
  clock_gettime(CLOCK_MONOTONIC, &end);
  printf("  %fs elapsed\n", (end.tv_sec-start.tv_sec) + ((float)(end.tv_nsec - start.tv_nsec))/1000000000);
  return 0;
}

以下是我运行时的结果:

-bash$ time strace -ttT -c ./open_stuff
  5.162448s elapsed <------ Output from C++ code

% time     seconds  usecs/call     calls    errors syscall 
------ ----------- ----------- --------- --------- ----------------
 99.72    0.043820          86       508           open  <------output from strace
  0.15    0.000064           0       508           close
  0.14    0.000061           0       705           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0         8           fstat
  0.00    0.000000           0        25           mmap
  0.00    0.000000           0        12           mprotect
  0.00    0.000000           0         3           munmap
  0.00    0.000000           0        52           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         3         1 futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.043945                  1834         2 total

real    0m5.821s  <-------output from time
user    0m0.031s
sys     0m0.084s

理论上,从C ++报告的“过去”时间应该是open(2)调用的执行时间加上执行for循环500次的最小开销。然而,来自strace的open(2)和close(1)调用的总时间总和缩短了99%。我无法弄清楚发生了什么。

PS C经过时间和系统时间之间的差异是由于files.csv实际上包含数以万计的路径,这些路径都被加载。

1 个答案:

答案 0 :(得分:7)

将经过时间与执行时间进行比较就像将苹果与橙汁进行比较一样。 (其中一个缺少纸浆:))要打开文件,系统必须找到并读取相应的目录条目...如果路径很深,则可能需要rrad一些目录条目。如果条目未缓存,则需要从磁盘读取它们,这将涉及磁盘搜索。当磁头移动时,当扇区旋转到磁盘头的位置时,挂钟一直在滴答作响,但CPU可以做其他事情(如果有工作要做。)所以算作经过的时间 - 不可阻挡的时钟开启 - 但不是执行时间。