考虑以下代码
#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,它应该是大约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
)
对于(可能是最丑陋的)解决方法,我当然可以测量很短的时间,将其与预期的差异进行比较并得出一个因素。但是我非常想优雅地解决这个问题。
答案 0 :(得分: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(嘿......)没有任何内在错误,但这是一个令人讨厌的问题!
答案 1 :(得分:0)
尝试明确使用 duration_cast(system_time :: now() - start).count()
答案 2 :(得分:0)
很多时候根据编译器版本区分代码是不可避免的。 我建议不在运行期间解决4.7和4.8之间的区别(你提到的丑陋&#39;解决方案)。 在编译时中执行此操作。
#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