为什么 C++ 时钟 return 睡眠后值更小?

Why does the c++ clock return smaller values after sleeping?

我正在尝试测量部分代码的性能,以便比较不同的统计方法。我注意到,如果我事先让线程休眠一段时间,测得的 cpu 时间会明显缩短。那里发生了什么?我用错了 clock() 吗?

我在 ubuntu 系统上使用 mpic++。

#include <ctime>
#include <chrono>

#include <cmath>
#include <random>

#include <iostream>

#include <thread>

int main(){

//If I include this line then the measured time is 10 times smaller
std::this_thread::sleep_for(std::chrono::milliseconds(1000));

std::default_random_engine generator;
std::normal_distribution<double> distribution = std::normal_distribution<double>(0.0,1.0);


int M= 100000;
double test = 0;

clock_t start = clock();
for(int counter=0;counter<M;counter++){
    test+=distribution(generator);
}
clock_t end = clock();

std::cout << "Generated "<<M<<" values in "<<((double) (end - start)) / CLOCKS_PER_SEC<<std::endl;
std::cout<<test;

return 0;
}

如果我让线程休眠,那么我会得到: Generated 100000 values in 0.01637

否则结果为: Generated 100000 values in 0.134786

Strace 结果 std::this_thread::sleep_for(std::chrono::milliseconds(1000));:

    % time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 99.21    0.455606      455606         1           nanosleep
  0.51    0.002321          18       130           read
  0.06    0.000272          27        10           brk
  0.04    0.000203           1       241           mmap
  0.04    0.000176           2       101        11 openat
  0.03    0.000117           1       178           mprotect
  0.03    0.000115           1        90           close
  0.02    0.000112          19         6           sched_getaffinity
  0.02    0.000111           1        93           fstat
  0.02    0.000072           8         9           clone
  0.01    0.000053          27         2           prlimit64
  0.01    0.000039          20         2           clock_gettime
  0.01    0.000028          28         1           getpid
  0.01    0.000028           1        24         1 futex
  0.00    0.000000           0         2           write
  0.00    0.000000           0         8         8 stat
  0.00    0.000000           0        15           munmap
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0        78        78 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         4           getdents
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           getrandom
------ ----------- ----------- --------- --------- ----------------
100.00    0.459253                  1003        98 total

没有std::this_thread::sleep_for(std::chrono::milliseconds(1000));的结果:


% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 32.00    0.002080          16       130           read
 20.23    0.001315           5       241           mmap
 14.00    0.000910           5       178           mprotect
 10.15    0.000660           7       101        11 openat
  5.41    0.000352           5        78        78 access
  4.66    0.000303           3        93           fstat
  4.43    0.000288           3        90           close
  2.81    0.000183          20         9           clone
  1.82    0.000118          10        12         1 futex
  1.08    0.000070           5        15           munmap
  0.80    0.000052           5        10           brk
  0.62    0.000040           7         6           sched_getaffinity
  0.57    0.000037          19         2           write
  0.43    0.000028           4         8         8 stat
  0.38    0.000025          13         2           clock_gettime
  0.18    0.000012           3         4           getdents
  0.15    0.000010           5         2           prlimit64
  0.14    0.000009           9         1           getpid
  0.03    0.000002           1         2           rt_sigaction
  0.03    0.000002           2         1           arch_prctl
  0.03    0.000002           2         1           getrandom
  0.02    0.000001           1         1           rt_sigprocmask
  0.02    0.000001           1         1           set_tid_address
  0.02    0.000001           1         1           set_robust_list
  0.00    0.000000           0         1           execve
------ ----------- ----------- --------- --------- ----------------
100.00    0.006501                   990        98 total

我找到了罪魁祸首。我在 eclipse 中工作,并且在同一个项目中有一个 header 和相应的 cpp 文件。直到 eclipse 链接文件,即使我不包含它们。此文件包含 class 和类型 dealii::FullMatrix:

的变量
//Coefficients.h

#ifndef COEFFICIENTS_H_
#define COEFFICIENTS_H_
#include <deal.II/lac/full_matrix.h>

class Coefficients{
public:
    Coefficients(int dim);
protected:
    dealii::FullMatrix<double> values;
};

#endif /* COEFFICIENTS_H_ */ 

在 cpp 文件中,构造函数初始化矩阵:

//Coefficients.cpp

#include "Coefficients.h"

Coefficients::Coefficients(int dim):values(dim,dim){};

这不知何故导致了时差。现在我只是将构造函数放在我的 header 文件中,这似乎可以解决问题。如果你们中有人知道那里发生了什么,我将非常感兴趣。

感谢您的讨论和所有有趣的答案。特别感谢 n.m。用于测试我的程序。