【发布时间】:2016-08-05 01:27:20
【问题描述】:
我在几台机器上测试了times()和clock_gettime(CLOCK_MONOTONIC),结果很混乱(每个api单线程运行10M次):
Thinkpad P50 Xeon E3-1505Mv5 [Skylake 14nm]:
times(NULL) : 450ms
clock_gettime(CLOCK_MONOTONIC): 325ms
你可以在 Skylake 上看到 clock_gettime 比时间快。
这是 Xeon E5-2430 [Sandy Bridge 32nm] 上的结果:
times(NULL) : 600ms
clock_gettime(CLOCK_MONOTONIC): 1420ms
times(NULL) 现在更快了。
我也在旧 Thinkpad W510 I7-720QM [Clarksfield 45nm] 上进行了相同的测试:
times(NULL) : 1.73s
clock_gettime(CLOCK_MONOTONIC): 20.4s
似乎有一些新的硬件实现了一些新功能,从而提高了clock_gettime的性能?
【问题讨论】:
-
如果您的目的是通过多次获取时钟来衡量性能,我建议您阅读stackoverflow.com/questions/34810392/… 以及
rdtscp。 -
不,我不使用此代码来衡量性能。我用它来计时一些计时器,但它可以非常频繁地启动。所以API本身的有效性非常重要。顺便说一句:windows GetTickCount64 API 非常快,在同一台 P50 机器上只需 60 毫秒。为什么linux这个功能比windows慢?
-
例如:判断我们是否需要发送下一个心跳包,或者检查一个用户会话是否保持有效等等。有很多“单调时间”的密集用法。
-
那为什么不使用操作系统提供的实际计时器呢?在 Linux 上,
timer_settime()或timerfd_settime().... -
上述问题的答案并不重要。
clock_gettime(CLOCK_MONOTONIC, &ts)足够快,绝不会成为理智使用的瓶颈。如果您发现自己使用得太频繁,请使用信号处理程序或专用线程来更新无锁/原子时间变量,并让用户检查它。 (在多线程进程中,您可能会受到缓存线乒乓的影响;有很多方法可以缓解这种情况。您还需要使用原子内置插件,但所有主要的 POSIXy C 编译器都提供了它们,所以事实证明也不会对便携性造成任何问题。)