0

我们有一个在Solaris(5.10,sparc 平台)上运行的多线程 C++ 应用程序。根据“pstack”,大多数线程似乎经常在下面的调用中等待太久。这对应time_t currentTime = time(NULL) ;于应用程序代码中的“”函数,以获取当前时间(以秒为单位)。

ffffffff76cdbe1c __time (0, 23e8, 1dab58, ffffffff76c63508, ffffffff76e3e000, 2000) + 8

时区是“亚洲/利雅得”。我尝试将 TZ 变量设置为“亚洲/利雅得”以及“ <GMT+3>-3”。但是这两种选择都没有明显的改善。此时更改服务器代码(即使有替代方法)相当困难。一个有 100 万次“”调用的测试程序(单线程,编译时没有 -O2)time(NULL)很快就出来了。应用程序和测试程序使用gcc 4.5.1.

还有什么我可以尝试的吗?

我同意这是一个相当广泛的问题。一旦有足够的改进来处理当前负载,我将尝试有效的建议并关闭它。

编辑 1:

请忽略上面对 time(NULL) 的引用,作为 __time 堆栈的可能原因。我根据签名进行了推断,并在源方法中找到了相同的调用。

以下是导致 __time 的另一个堆栈。

ffffffff76cdbe1c __time (0, 23e8, 1dab58, ffffffff773e5cc0, ffffffff76e3e000, 2000) + 8
ffffffff76c9c7f0 getnow (ffffffff704fb180, ffffffff773c6384, 1a311c, 2, ffffffff76e4eae8, fffc00) + 4
ffffffff76c9af0c strptime_recurse (ffffffff76e4cea0, 1, 104980178,   ffffffff704fb938, ffffffff704fb180, ffffffff704fb1a4) + 34
ffffffff76c9dce8 __strptime_std (ffffffff76e4cea0, 10458b2d8, 104980178, ffffffff704fb938, 2400, 1a38ec) + 2c
4

2 回答 2

1

您(和我们)将无法做得time更快。从您的消息中,我了解到您同时从许多不同的线程中调用它。这可能是个问题;Solaris 很可能会序列化这些调用,因此最终会有很多线程等待其他线程完成。

您需要多少准确度?一个可能的解决方案可能是让一个线程循环读取时间,每次读取之间可能休眠 10 毫秒,并将结果放入一个全局变量中,其他线程读取该变量。(不要忘记您需要同步对变量的所有访问,除非您有某种原子变量,例如std::atomic<time_t>在 C++11 中。)

于 2013-07-25T14:15:19.763 回答
1

请记住,pstack这不仅会立即中断您的程序并生成堆栈。它必须抓住调试级别的控制,如果time调用足够频繁,它可能会大大过度指示调用,time因为它利用这些系统调用来控制您的应用程序来打印堆栈。

这些time调用很可能不是您真正的性能问题的根源。我怀疑您会想要使用诸如gprof(with g++ -p) 之类的分析器。或者,您可以利用一些 dtrace 工具包并使用hotuserdtrace 脚本,该脚本将对您正在运行的应用程序的用户代码进行基本的统计分析。

time返回 UTC 时间,因此任何更改TZ都不应该对其调用时间产生任何影响。

如果在分析之后,事实证明这time确实是罪魁祸首,那么您可能能够缓存time调用中的值,因为它每秒不会更改超过一次。

于 2013-07-25T14:36:52.230 回答