首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与std::chrono::system_clock / std::chrono::high_resolution_clock的时间差

与std::chrono::system_clock / std::chrono::high_resolution_clock的时间差
EN

Stack Overflow用户
提问于 2014-02-21 14:34:23
回答 3查看 10K关注 0票数 12

考虑下面的代码

代码语言:javascript
复制
#include <chrono>
#include <iostream>
#include <thread>

int main()
{
   using std::chrono::system_clock;
   using std::chrono::milliseconds;
   using std::chrono::nanoseconds;
   using std::chrono::duration_cast;
   const auto duration = milliseconds(100);
   const auto start = system_clock::now();
   std::this_thread::sleep_for(duration);
   const auto stop = system_clock::now();
   const auto d_correct = duration_cast<nanoseconds>(duration).count();
   const auto d_actual = duration_cast<nanoseconds>(stop - start).count();
   std::cout << "Difference is " << d_actual << ", and it should be roughly " << d_correct << "\n";
}

我们所期待的是

差是100039989,大概是100000000。

请参见这个演示,在那里它的工作非常好。

但是,根据这个答案在堆栈溢出上,在我的机器上安装了几个编译器,它们似乎会导致配置错误。

因此,我尝试了建议的修复:设置正确的LD_LIBRARY_PATH。这些是我尝试过的与输出的组合(包括4.4和4.6.)

代码语言:javascript
复制
g++-4.7 time.cpp -pthread -std=c++11; LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.7/ ./a.out

差是100126,大概是100000000。

代码语言:javascript
复制
g++-4.7 time.cpp -pthread -std=c++11; LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.8/ ./a.out

差是100132,大概是100000000。

代码语言:javascript
复制
g++-4.8 time.cpp -pthread -std=c++11; LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.7/ ./a.out

差是100085953,大概是100000000。

代码语言:javascript
复制
g++-4.8 time.cpp -pthread -std=c++11; LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.8/ ./a.out

差是100156418,大概是100000000。

不管如何,使用g++-4.8编译都可以很好地使用任何libstdc++,而用g++-4.7编译则会导致崩溃的情况。

在编译器/二进制调用中,我做了什么错误吗?还是g++-4.7中的一个bug?(具体而言,是g++-4.7.3g++-4.8.1 )

为了(可能是最丑陋的)解决办法,我当然可以测量一小段时间,将它与预期的差异进行比较,并得出一个因素。不过,我很想巧妙地解决这个问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-06-28 03:32:15

我不能评论,但这似乎只是duration_cast的一个问题.我把你的睡眠撞到了1000毫秒,而且还违背了时间效用。事实上,它确实睡了1秒。

代码语言:javascript
复制
#include <chrono>
#include <iostream>
#include <thread>

int main()
{
   using std::chrono::system_clock;
   using std::chrono::milliseconds;
   using std::chrono::nanoseconds;
   using std::chrono::duration_cast;
   const auto duration = milliseconds(1000);
   const auto start = system_clock::now();
   std::this_thread::sleep_for(duration);
   const auto stop = system_clock::now();
   const auto d_correct = duration_cast<nanoseconds>(duration).count();
   const auto d_actual = duration_cast<nanoseconds>(stop - start).count();
   std::cout << "Difference is " << d_actual << ", and it should be roughly " << d_correct << "\n";
}

使用time实用程序运行它:

代码语言:javascript
复制
g++-4.7 time.cpp -pthread -std=c++11; time LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.7/ ./a.out
Difference is 1000193, and it should be roughly 1000000000

real    0m1.004s
user    0m0.000s
sys     0m0.000s

因此,的确,这看起来确实是ABI的一个问题。我的系统对于使用新版本的libstdc++和您的系统一样愚蠢。我们可以用ldd和/或LD_DEBUG=files确认这一点:

代码语言:javascript
复制
ldd a.out 
    linux-vdso.so.1 =>  (0x00007fff139fe000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff0595b7000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff0593a1000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff059183000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff058dba000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff058ab5000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ff0598e6000)

冒烟枪!这绝对不是正确的libstdc++..。我所做的一切都阻止不了它!

我的下一个实验是尝试使用静态libstdc++ (http://www.trilithium.com/johan/2005/06/static-libstdc/)链接:

代码语言:javascript
复制
ln -s `g++-4.7 -print-file-name=libstdc++.a`
g++-4.7 -static-libgcc -L. time.cpp -pthread -std=c++11; time ./a.out
Difference is 1000141417, and it should be roughly 1000000000

real    0m1.003s
user    0m0.004s
sys     0m0.000s

一切都好了!所以总的来说你是安全的。GCC 4.7 (呵呵.)没有什么固有的问题,但这是一个多么令人讨厌的问题!

票数 8
EN

Stack Overflow用户

发布于 2014-03-05 07:44:01

尝试显式使用duration_cast(system_time::now() - start).count()

票数 0
EN

Stack Overflow用户

发布于 2014-05-27 14:15:41

很多时候,根据编译器版本来区分代码是不可避免的。我建议不要在运行时解决4.7和4.8之间的差异(您提到的“丑陋”解决方案)。而是在编译时这样做。

代码语言:javascript
复制
#if __GNUC__ == 4 && __GNUC_MINOR__ > 7
   // your gcc 4.8 and above code here
#else
   // your gcc 4.7.x and below code here
#endif
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21937257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档