- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我跟踪了一个 java 进程,该进程触发了大量内核时间来查看正在使用哪些系统调用,并且惊讶地发现 gettimeofday()
和clock_gettime()
占主导地位(我怀疑这是由于日志记录),考虑到 man vdso
,这很奇怪状态:
使用strace(1) 跟踪系统调用时,vDSO 导出的符号(系统调用)不会出现在跟踪输出中。
为什么会发生这些系统调用?有办法避免它们吗?
该计算机正在 EC2 上运行 Ubuntu 16.04.1。
为了让事情变得更简单,我用 C 创建了一个最小的测试程序 ( testgtod.c
):
#include <stdlib.h>
#include <sys/time.h>
void main(void)
{
struct timeval tv;
for(int i = 0; i < 1000; i++) {
/* glibc wrapped, shouldn't actually syscall */
gettimeofday(&tv, NULL);
}
}
然后我在 strace 下编译并运行该程序:gcc testgtod.c -o testgtod && sudo strace ./testgtod
与我的预期不同,输出包括一千次对 gettimeofday() 的调用。
我测试过的东西以确保我没有看到东西:
使用 file
确保二进制文件是 64 位 elf
ldd ./testgtod
确保 vDSO 处于事件状态:
linux-vdso.so.1 => (0x00007ffcee25d000)libc.so.6 =>/lib/x86_64-linux-gnu/libc.so.6 (0x00007f6f6e161000)/lib64/ld-linux-x86-64.so.2 (0x0000559ed71f3000)
getauxval(AT_SYSINFO_EHDR) != NULL
已替换gettimeofday(&tv, NULL)
调用 syscall(SYS_gettimeofday, &tv, NULL)
,调用数量增加到 1000 万,运行在 time
之下。 - 两种情况下的运行时行为相同:./testgtod 0.16s user 0.83s system 99% cpu 0.998 total
.
最佳答案
该问题与 Xen 上运行的虚拟机有关,具体来说,Xen 时钟源尚不允许 vDSO 访问时钟:
ubuntu@machine:~% cat /sys/devices/system/clocksource/*/current_clocksource
xen
然后,我将时钟源更改为 tsc
:
ubuntu@machine:~% sudo sh -c "echo tsc >/sys/devices/system/clocksource/clocksource0/current_clocksource"
注意:不建议移至 tsc
生产机器上的时钟源,因为它可能会导致时钟向后漂移。
参见https://blog.packagecloud.io/eng/2017/03/08/system-calls-are-much-slower-on-ec2/有关 vDSO 和时钟源之间交互的详细文章。
注2:看起来tsc
Xen 中的支持在版本 4.0 中得到了改进,并且 Sandy Bridge+ 平台中的 CPU 支持得到了改进。现代 EC2 机器应该可以使用 tsc
。使用 dmesg | grep "Xen version"
检查 Xen 版本。亚马逊推荐tsc
时钟源已在 re:Invent 2015 中 ( https://www.slideshare.net/AmazonWebServices/cmp402-amazon-ec2-instances-deep-dive )。我还没有将其投入生产,但情况似乎并不像 packagecloud 所暗示的那么糟糕。
补充阅读:
Why rdtsc
interacts poorly with VMs
Xen's 4.0 rdtsc changes
Linux kernel timekeeping documentation, discussing the pitfalls of the TSC
关于amazon-ec2 - gettimeofday() 不使用 vDSO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42622427/
#include #include int main() { float time; struct timeval tv; gettimeofday( &tv, NULL );
gettimeofday根据 this page 是 x86-86 的系统调用(只需在框中搜索 gettimeofday): int gettimeofday(struct timeval *tv,
我需要使用函数 gettimeofday 进行家庭作业,在阅读手册页并查看一些在线示例后,我不明白为什么人们有时同时使用结构的 tv_sec 成员和结构的 tv_usec 成员。 手册页指出: T
如果在我测量间隔时发生时间变化,会发生什么情况,例如: gettimeofday(&start, NULL); system("./anotherProgram"); // during the
是否有任何方法可以在不使用任何数组的情况下存储 gettimeofday() 中的时间刻度数并将其格式化为某种特定方式(例如“%m-%d-%Y %T”)? 这将为计算当前时间的程序的每个实例节省内存。
当我输出 gettimeofday() 的微秒字段时,我注意到微秒字段大于 1,000,000。有人知道为什么吗?这是否意味着我对 gettimeofday() 的解释是错误的? 郑重声明,我的假设是
我正在用 c 编写一些基本的东西,计算执行 shell 脚本所需的时间。 我有 gettimeofday(&start, NULL); // code here gettimeofday(&end,
我想获取一个线程进入临界区和另一个线程获得进入 ARM CortexA8 上同一临界区的权限之间耗时。为此,我一直在使用 C 语言中的 gettimeofday() 函数。 void *Thre
对于以下代码,我有时会得到负值。我不明白这一点。任何人都可以解释为什么会发生这种情况。 int64_t gettimelocal() { struct timeval Time; if
/* * Returns time in s.usec */ float mtime() { struct timeval stime; gettimeofday(&stime,0
我为我所在大学的抽样作业编写了这段代码。 #include #include #include #include int main(int argc, char **argv){ st
我正在尝试以十分之一秒的精度打印 ISO-8601 中的时间。YYYY-MM-DDThh:mm:ss.s 这是我的代码: #include #include #include #include
我有一个程序可以计算发布-订阅模型中对象的延迟时间。我为时间戳使用了以下函数: uint64_t GetTimeStamp() { struct timeval tv; gettime
我试过谷歌、php.net 和 php 邮件列表的存档,但我找不到我在找什么。也许这是显而易见的,或者也许没有人想知道这…… 多年来,我一直使用 microtime() 来获取当前时间,包括微秒。然而
如何将此功能从 linux 转换到 Windows?我不能使用 gettimeofday 函数 double getSysTime() { struct timeval tp; getti
我正在编写一个线程库,在安排线程时我需要知道它们已经准备了多长时间。每个 Thread 实例都有一个 timeval _timeInReady 字段,当我将一个实例推送到就绪队列时,我调用这个函数:
我正在将最初为 Win32 API 编写的游戏移植到 Linux(嗯,将 Win32 端口的 OS X 端口移植到 Linux)。 我已经实现了 QueryPerformanceCounter,方法是
我正在尝试计算系统调用的平均开销,因此我重复执行 0 字节读取系统调用,并将平均开销计算为时间差除以迭代次数。但是,有时当我这样做时,我会得到一个负数。这是我的代码: #include #inclu
我正在做一个涉及比较编程语言的项目。我正在计算阿克曼函数。我测试了 Java、Python 和 Ruby,得到了 10 到 30 毫秒之间的响应。但是 C++ 似乎需要 125 毫秒。这是正常的,还是
我正在尝试使用 gettimeofday 或 cudaEventRecord 来计时循环。然而,他们报告的结果截然不同。这是伪代码: // get time here (start) whil
我是一名优秀的程序员,十分优秀!