与std::chrono::system_clock/std::chrono::high_resolution_cloc
time differences with std::chrono::system_clock / std::chrono::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
看看这个演示,它的工作原理非常好。
然而,在我的机器上,安装了几个编译器,根据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,应该大约为100000000
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,应该大约为100000000
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
中的错误?(具体为g++-4.7.3
和g++-4.8.1
)
对于(可能是最丑陋的)变通方法,我当然可以测量一小段时间,将其与预期差异进行比较,然后得出一个因素。然而,我非常想优雅地解决这个问题。
我不能发表评论,但这似乎只是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本质上没有什么问题(呵呵…),但这是一个多么糟糕的问题!
try显式使用duration_cast(system_time::now()-start).count()
很多时候,根据编译器版本来区分代码是不可避免的。我建议不要在运行时解决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
- 从持续时间构造std::chrono::system_clock::time_point
- 如何在c++迭代器类型中包装std::chrono
- 使用 memcpy() 复制到 std::chrono::milliseconds 会给出错误 -Werror=clas
- std::adjacent_difference with std::chrono time_point
- 是否确保 2 个连续的 std::chrono::steady_clock::now() 不相等?
- std::chrono::d uration 可以按秒初始化,但不能按毫秒初始化?
- 比较两个 std::chrono::time_point 实例时出错
- 来自 std::chrono 的编译器警告,但未被使用
- 从编译时已知的日历日期创建"std::chrono::time_point"
- std::chrono::time_point from std::string
- 使用 std::chrono::steady_clock 对线程/异步中的代码进行基准测试
- 为什么 std::chrono 在测量循环和编译器优化的并行 OpenMP 的执行时间时不起作用?
- What is the std::chrono::time_point equivalent of std::numer
- python equivalent of std::chrono::steady_clock::now();
- std::chrono::duration::count函数的实际结果类型是什么
- C++,自使用boost和std::chrono的纪元以来的时间?为什么 Boost 版本慢 10 倍?
- std::hash for std::chrono::duration
- 如何使用 std::chrono 库设置特定时间?
- C++ 中计时的逻辑错误(使用 std::chrono)
- std::chrono 在从 main 或 from 类方法使用时给出不同的值