2014-02-21 47 views
12

考虑下面的代码用的std ::时辰:: SYSTEM_CLOCK /的std ::计时时间差:: high_resolution_clock

#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

请参阅this demo它在哪里工作绝对好。

但是,在我的机器上,根据this answer here on Stack Overflow安装了几个似乎会导致错误配置的编译器。

因此我尝试了建议的修复方法:设置正确的LD_LIBRARY_PATH。 这些是与输出组合我试图(除其他与4.4和4.6 ...)

g++-4.7 time.cpp -pthread -std=c++11; LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.7/ ./a.out 

差异是100126,并且它应该是大致亿

g++-4.7 time.cpp -pthread -std=c++11; LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.8/ ./a.out 

差值为100132,应该大致为100000000

g++-4.8 time.cpp -pthread -std=c++11; LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.7/ ./a.out 

不同的是100085953,它应该大致亿

g++-4.8 time.cpp -pthread -std=c++11; LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.8/ ./a.out 

不同的是100156418,它应该大致亿

看来,无论怎么样,与g++-4.8编译使用任何libstdc++工作正常,而与g++-4.7编译导致断开坐uation。

我在编译器/二进制调用这里做错了什么,或者它是g++-4.7中的错误? (这是g++-4.7.3g++-4.8.1要具体)

对于(可能的最难看)的解决方法,我可以的时候微量当然措施,它比较与预期的差异,并拿出一个因素。不过,我很想优雅地解决这个问题。

+0

如果有帮助,此页面提到C++ 11时钟ABI在GCC 4.8.1中发生了变化:http://gcc.gnu.org/gcc-4.8/changes.html –

+0

@JohnZwinck这可能与此有关,但我没有看到4.7怎样才能解决这个问题(我希望至少有两个编译器版本适用于我正在开发的产品。在工作中,只有我的开发机器有4.8,所有其他机器运行的不足4.7) – stefan

+0

GCC 4.7没有为C++ 11提供100%的工作支持,所以你可能会在那里运气不佳,或者至少需要一些讨厌的解决方法。我不太确定,也无法从GCC网站挖掘更具体的问题报告。 –

回答

8

我不能发表评论,但它似乎是与duration_cast一个问题只...我撞到你的睡眠高达1000毫秒,并运行它相对于时间的效用。确实,它睡了1秒。

#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"; 
} 

随着时间的工具运行它:

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来确认:

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/)链接:

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(heh ...)没有任何内在的错误,但是这是一个不好的问题!

+1

最后一个理智的答案!谢谢:) – stefan

+1

D'aw,shucks!我的第一个! – ftwl

+2

我知道,我必须说:遇到一个好的第一个答案是非常罕见的。请留在这个网站:) – stefan

0

尽量明确地使用 duration_cast(SYSTEM_TIME ::现在() - 启动).Count之间的()

+0

我想我应该在我的问题上更加精确。我编辑显示duration_cast不能解决问题。 – stefan

+0

也许你的g ++ 4.7的头文件有问题?如果库标头不正确地定义纳秒,则会导致此问题。尝试不同版本的g ++ 4.7,或者您可以简单地查看头文件。 – wacky6

+0

纳秒的定义取决于'纳米'的比例,并且对于所有版本(4.4,4.6,4.7和4.8)都是相同的。 – stefan

0

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

#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 
相关问题