2016-05-27 5 views
1

Ich verfolge die Ausführungszeit einer Methode innerhalb und außerhalb der Methode. Ich benutze ROS, um die Zeit zu bekommen, weil dies alles in einem ROS-Paket ist und es ist einfach sehr praktisch. Die Dokumentation finden Sie hier: http://wiki.ros.org/roscpp/Overview/Time.Lange Zeit von einer Methode zurückzukehren C++

void ClassName::my_method() 
{ 
    ros::Time t_start = ros::Time::now(); 
    // do stuff 
    ros::Duration d_execution = ros::Time::now() - t_start; 
} 

void ClassName::Func() 
{ 
    ros::Time t_total = ros::Time::now(); 
    my_method(); 
    ros::Duration d_total = ros::Time::now() - t_total; 
} 

Das Problem, das ich habe ist, dass d_total als d_execution immer deutlich länger ist.

d_execution wird normalerweise 20-40 Mikrosekunden, aber d_total wird rund 150 Mikrosekunden sein.

Ich kann nicht herausfinden, warum das passiert. Mein Verständnis ist, dass das einzige, was am Ende einer Methode geschieht, die Freigabe von Speicher ist, der auf dem Stapel in der Methode erstellt wurde. Allerdings habe ich den Code neu geschrieben, um nur etwa die Hälfte der Variablen zu erstellen, und ich sah keine Änderung in d_total. Was kann sonst noch passieren, damit die Funktion so lange zurückkehrt? Jede Hilfe wird geschätzt.

Edit: Ich habe die Zeit für ros :: Time :: now() gemessen und es scheint zu vernachlässigen.

time_t now, then; 
    time(&now); 
    ros::Time t = ros::Time::now(); 
    time(&then); 
    printf("t1-t0: %f", difftime(now, then)); 

Der Ausgang ist "t1-t0: 0.000000".

Außerdem sind alle Variablen, die auf dem Stapel in der Methode zugeordnet sind, doppelt vorhanden. Die einzigen Ausnahmen sind zwei std :: vectors, die nur 2-3 Elemente enthalten.

+3

Wie lange dauert ein leerer Methodenaufruf? – tadman

+0

Wie viele Testläufe hast du gemacht? Hast du den Assemblercode überprüft? –

+0

Wie viele Aufgaben laufen Sie im Hintergrund? Der Scheduler könnte die Verzögerung verursachen. –

Antwort

0

Bei der Rückkehr ruft eine Methode Destruktoren für alles auf, das auf der obersten Ebene deklariert ist. Diese Destruktoren können mehr Destruktoren aufrufen und so weiter.

Außerdem können die Registerwerte bei der Rückkehr wiederhergestellt werden, aber das würde kaum 100 Mikrosekunden dauern.

Das Freigeben des Stapelspeichers erfolgt durch Ändern des Stapelzeigerwerts, der sehr schnell ist (wahrscheinlich ein Befehl).

1

Wie viel Unterschied wird mit dieser genauen Version von my_method() sein?

Ist my_method virtuell?

Wenn Sie Leistungstests durchführen, ist es eine natürlichere Methode, Perzentile anstelle von Durchschnittswerten anzuzeigen.

Dies ist wäre richtiger Weg, um den Unterschied zu messen:

void ClassName::my_method() 
{ 
    ros::Time t_start = ros::Time::now(); 
    { // note this 
    // do stuff 
    } // and node this, destructors will be run before the next line 
    ros::Duration d_execution = ros::Time::now() - t_start; 
} 

Unter Linux/OSX können Sie versuchen, clock_gettime() zu verwenden, was ich in der Regel in Performance-Tests verwenden. In C++ können Sie std :: chrono :: duration (http://en.cppreference.com/w/cpp/chrono/duration) versuchen. Wahrscheinlich ros :: Zeit haben eine große Zeit zu jittern.

+0

Hallo, ich habe versucht, Ihren Ansatz und sah keine Veränderung. Vielen Dank für die Information, wie man den Unterschied richtig misst. – Sterling

Verwandte Themen