2009-07-14 17 views
1

Ich führe einige Profiling-Tests durch, und usleep ist eine nützliche Funktion. Aber während mein Programm schläft, erscheint diese Zeit nicht im Profil.Wie mache ich einen aktiven Schlaf?

z. wenn ich eine Funktion wie haben:

void f1() { 
    for (i = 0; i < 1000; i++) 
     usleep(1000); 
} 

mit Profilwerkzeugen wie gprof, ist f1 scheint keine Zeit zu verbrauchen.

Was ich suche ist eine Methode, schöner als eine leere while-Schleife für einen aktiven Schlaf zu tun, wie:

while (1) { 
    if (gettime() == whatiwant) 
     break; 
} 
+0

Danke für die Antwort. Vielleicht war es nicht wirklich klar, aber es ist mir egal, wie effizient es ist, ich führe einige Tests durch (eigentlich werde ich das in einer test.c-Datei verwenden ...). Ich bin mir der Wartelistenplanung und so weiter bewusst. Was ich suche, ist eine existierende Methode für das, was ich aktualisiert habe. –

Antwort

2

Was für ein System sind Sie? In UNIX-ähnlichen Systemen können Sie mithilfe von setitimer() ein Signal nach einer bestimmten Zeit an einen Prozess senden. Dies ist die Einrichtung, die Sie benötigen, um den Typ des "aktiven Schlafs" zu implementieren, den Sie suchen.

Stellen Sie den Timer ein und wiederholen Sie die Schleife, bis Sie das Signal empfangen.

+0

Wunderbar, genau das, was ich suche !! Vielen Dank –

2

Weil, wenn Sie die CPU rufen usleep wird gesetzt, um etwas anderes für 1 Sekunde zu arbeiten. Der aktuelle Thread verwendet also keine Prozessorressourcen, und das ist sehr clever.

Ein aktiver Schlaf ist etwas, das man unbedingt vermeiden sollte, weil es eine Verschwendung von Ressourcen ist (was letztendlich die Umwelt schädigt, indem man Elektrizität in Wärme umwandelt;)).

Wie auch immer, wenn Sie das wirklich tun wollen, müssen Sie dem Prozessor eine echte Arbeit geben, etwas, das durch Compiler-Optimierungen nicht ausgeklammert wird. Zum Beispiel

for (i = 0; i < 1000; i++) 
    time(NULL); 
2

Ich nehme an, Sie den Gesamtbetrag der Zeit, um herauszufinden, wollen (Wandtaktzeit, Echtweltzeit, die Zeit, die Sie sitzen Ihre Anwendung laufen zu beobachten) f1() nimmt, im Gegensatz zur CPU Zeit. Ich würde untersuchen, ob gprof Ihnen eine Wanduhrzeit anstatt einer Bearbeitungszeit geben kann.

Ich denke, es hängt von Ihrem Betriebssystem ab, aber der Grund, warum Sie uns nicht als Prozesszeit im Profil sehen sehen, ist, weil es technisch während dieser Zeit keine anderen Prozesse verwendet (vorausgesetzt, dies ist läuft auf einer * nix-Plattform).

+0

Ich denke du meinst Echtzeit/Wanduhrzeit. Schlafen sollte keine Benutzerzeit verwenden. – Nick

+0

@Nick - Wahr. Bearbeiten gemacht. –

+0

Hm, nette Antwort. Bereits in gprof gesucht, ist das nicht möglich. –

1
for (int i = i; i < SOME_BIG_NUMBER; ++i); 

Der gesamte Punkt in "Schlaf" -Funktionen ist, dass Ihre Anwendung nicht ausgeführt wird. Es wird in eine Schlafwarteschlange versetzt, und das Betriebssystem überträgt die Steuerung an einen anderen Prozess. Wenn Sie möchten, dass Ihre Anwendung ausgeführt wird, aber nichts tut, ist eine leere Schleife eine einfache Lösung. Aber Sie verlieren alle Vorteile des Schlafs (lassen Sie andere Anwendungen laufen, spart CPU-Auslastung/Stromverbrauch)

Also was Sie fragen, macht keinen Sinn. Sie können Ihre Anwendung nicht schlafen lassen, aber weiterhin ausgeführt werden.

+1

Wenn das kompiliert würde, wäre es in der Tat eine mächtige lange Schleife. :) Sie vermissen den "i ++" Teil. – unwind

+0

haha, oops – jalf

+0

Abgesehen davon Typo, hat er grundsätzlich Recht (oder C++ ly ??) Ich bin sicher, dass jemand mit einem großen Vertreter wird es reparieren, wenn er es nicht tut! –

0

AFAIK die einzige Option ist eine While-Schleife. Das Betriebssystem geht im Allgemeinen davon aus, dass Sie eine bestimmte Zeit warten müssen, bis Sie dem Betriebssystem nachgeben.

Die Möglichkeit, einen genauen Mikrosekunden-Timer zu erhalten, ist ebenfalls ein potenzielles Problem. AFAIK gibt es keine plattformübergreifende Art Timing zu machen (bitte korrigieren Sie mich, weil ich einen plattformübergreifenden Sub-Mikrosekunden-Timer lieben würde!: D). Unter Win32 können Sie eine Schleife mit einigen QueryPerformanceCounter-Aufrufen umrunden, wenn Sie genügend Zeit in der Schleife verbracht und dann beendet haben.

beispiels

void USleepEatCycles(__int64 uSecs) 
{ 
    __int64 frequency; 
    QueryPerformanceFrequency((LARGE_INTEGER*)&frequency); 
    __int64 counter; 
    QueryPerformanceCounter((LARGE_INTEGER*)&counter); 

    double dStart = (double)counter/(double)frequency; 
    double dEnd = dStart; 
    while((dEnd - dStart) < uSecs) 
    { 
     QueryPerformanceCounter((LARGE_INTEGER*)&counter); 
     dEnd = (double)counter/(double)frequency; 
    } 
} 
0

Aus diesem Grund ist es wichtig, beim Profiling die Zeit "Ausgeschaltete%" zu berücksichtigen. Grundsätzlich kann die exklusive Zeit Ihrer Funktion wenig sein, wenn sie z.B. I/O, DB usw., auf externe Ressourcen wartend, dann "Ausgeschaltet%" ist die Metrik, auf die man achten sollte.

0

Dies ist die Art von Verwirrung, die Sie mit Gprof bekommen, denn was Sie interessieren, ist Wanduhrzeit. Ich benutze this.