2017-03-06 1 views
1

Ich habe einen Java-Prozess verfolgt, der eine Menge Kernel-Zeit ausgelöst hat, um zu sehen, welche syscalls verwendet wurden, und war überrascht, dass gettimeofday() und clock_gettime() dominiert (ich vermute, dass es aufgrund der Protokollierung ist), was seltsam ist, wenn man bedenkt, dass man vdso states:gettimeofday() ohne vDSO?

Bei der Rückverfolgung von Systemaufrufen mit strace (1) werden Symbole (Systemaufrufe), die vom vDSO exportiert werden, nicht in der Trace-Ausgabe angezeigt.

Wie kommen diese Systemaufrufe? Gibt es eine Möglichkeit, sie zu vermeiden?

Die Maschine läuft Ubuntu 16.04.1 auf EC2.

Um die Dinge zu vereinfachen, habe ich ein minimales Testprogramm in 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); 
    } 
} 

ich dann das Programm unter strace kompiliert und lief: gcc testgtod.c -o testgtod && sudo strace ./testgtod

Der Ausgang tausend Anrufe enthalten gettimeofday(), trotz meiner Erwartung.

Dinge, die ich getestet, um sicherzustellen, ich sehe die Dinge nicht:

  1. sorgte dafür, dass der binäre ist eine 64-Bit-Elf file

  2. ldd ./testgtod mit, um sicherzustellen, vDSO aktiv ist:

    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)

  3. getauxval(AT_SYSINFO_EHDR) != NULL

  4. ersetzt gettimeofday(&tv, NULL) Anrufe mit syscall(SYS_gettimeofday, &tv, NULL), bis 10 Anzahl der Anrufe erhöht Millionen, lief unter time - Laufzeitverhalten war das gleiche in beiden Fällen: ./testgtod 0.16s user 0.83s system 99% cpu 0.998 total.

Antwort

2

Die Frage dazu eine VM ist auf Xen laufen, die speziell auf die Uhr für vDSO Zugang erlaubt es, die Xen Clock noch nicht verwandt ist:

[email protected]:~% cat /sys/devices/system/clocksource/*/current_clocksource 
xen 

geändert Dann habe ich die Clock zu tsc:

[email protected]:~% sudo sh -c "echo tsc >/sys/devices/system/clocksource/clocksource0/current_clocksource" 

HINWEIS: es nicht empfohlen wird, um die tsc Clock zu bewegen auf Produktionsmaschinen, da es für die Uhr Rückwärtsdrift verursachen kann.

Eine ausführliche Beschreibung der Interaktion zwischen vDSO und der Taktquelle finden Sie unter https://blog.packagecloud.io/eng/2017/03/08/system-calls-are-much-slower-on-ec2/.

ANMERKUNG 2: es scheint tsc Unterstützung in Xen mit Version 4.0 und mit einem verbesserten CPU-Unterstützung in Sandy Bridge + Plattformen verbessert hat. Moderne EC2-Maschinen sollten mit tsc in Ordnung sein. Überprüfen Sie die Xen-Version mit dmesg | grep "Xen version". Amazon empfahl die tsc Taktquelle bereits in re: Invent 2015 (https://www.slideshare.net/AmazonWebServices/cmp402-amazon-ec2-instances-deep-dive). Ich laufe noch nicht mit der Produktion, aber die Situation scheint nicht so schlimm zu sein, wie es von packagecloud impliziert ist.

Zusätzlicher Lesestoff:
Why rdtsc interacts poorly with VMs
Xen's 4.0 rdtsc changes
Linux kernel timekeeping documentation, discussing the pitfalls of the TSC