为什么 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。用于测试我的程序。
我正在尝试测量部分代码的性能,以便比较不同的统计方法。我注意到,如果我事先让线程休眠一段时间,测得的 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。用于测试我的程序。