Exakte Rechenzeit verbrauchen



  • Hallo,
    ich hoffe ich bin mit meiner Frage im richtigen Sub-Forum gelandet.

    Im Rahmen eines kleinen Projektes habe ich eine Funktion geschrieben, die ziemlich exakt 1 Sekunde an Rechenzeit (nicht reale Zeit, sondern wirklich Rechenzeit verbraucht).

    void secFunc()
    {
            UInt32 i = 0;
    	clock_t start, end;
    
    	start = clock();
    
    	while(end < (start+CLOCKS_PER_SEC))
    	{
    		++i;
    		end = clock();
    	}
    }
    

    Das funktioniert soweit auch gut, solange ich innerhalb des Programms keine nebenläufigen Aufgaben habe, die ebenfalls Rechenzeit verbrauchen und somit den clock Wert selbst verändert. Ich möchte daher die Funktion nun dahingehend abwandeln, dass auch bei nebenläufigen Aufgaben, exakt eine Sekunde an Rechenzeit verbraucht wird. Eine erste Idee, war eine Schleife zu schreiben, die in etwa so aussieht. Allerdings ist das auch nur eine Theorie, wie man es machen könnte, da ich nicht weiß ob es irgendwas gibt, dass genau ein Clock verbraucht. Vielleicht habt ihr ja noch andere Ideen? (Simple sleep() Funktionen sind relativ ungenau)

    void secFunc()
    {
        	UInt32 i;
    	for(i=0; i<CLOCKS_PER_SEC; ++i)
    	{
    		consume_one_clock;
    	}
    }
    

    Danke schon mal


  • Mod

    Bevor wir dir vernünftig helfen können, solltest du uns erklären, wozu das gut sein soll. Jetzt sag bitte nicht "um eine Funktion zu haben, die 1 Sekunde Rechenzeit verbraucht", sondern warum du so etwas brauchst und was du damit machen möchtest.



  • Simple sleep() Funktionen sind relativ ungenau

    Welche Genauigkeit moechtest du? Warum moechtest du diese Genauigkeit? Was ist mit Timern? Was ist mit betriebsspezifischen Funktionen wie WaitOnSingleObject ?



  • Es geht im Endeffekt um eine Simulation von verschiedenen Real-Time Tasks. Jede Task hat dabei bestimmte Parameter (Periode, Execution-Time und eine Deadline).

    Das Programm ist in der Lage verschiedene Tasks mit ihren spezifischen Periodenlängen auszuführen und erkennt, ob eine Task bis zu seiner Deadline seine Aufgabe (die zu schreibende Testfunktion) abgearbeitet hat.

    Es soll dann anschließend mit verschiedenen Scheduling-Algorithmen testst durchgeführt werden.



  • knivil schrieb:

    Simple sleep() Funktionen sind relativ ungenau

    Welche Genauigkeit moechtest du? Warum moechtest du diese Genauigkeit? Was ist mit Timern? Was ist mit betriebsspezifischen Funktionen wie WaitOnSingleObject ?

    Bei Timern hab ich das selbe Problem, wie in der Lösung oben. Angenommen zwei Tasks(Funktionsaufrufe) passieren "gleichzeitig" (Zeitpunkt t=0) und haben jeweils eine Execution Time von 2 sec. Beide Task würden damit einen Endzeitpunkt (t=2) haben (Timerevent). Der Scheduling-Algo teilt nun den Timeslot (0,1) Task 1 zu und den Timeslot (1,2) Task 2. Insgesamt wäre damit der Zeitpunkt t=2 erreicht, aber beide Task hätten erst 1 Zeiteinheit an Rechenkapazität zu verfügung gehabt und würden beedet werden

    Genauigkeit sollte ziemlich hoch sein. Weiß grade nicht, welche Genauigkeit das Simulationssystem zulässt.

    WaitOnSingleObject ist mir nicht bekannt. (Betriebssystem ist ein QNX in der Version 6.5



  • Fuer Windows auf die schnelle:

    void my_sleep(int ms)
    {
        HANDLE tmp = CreateEvent(0, 0, 0, 0);
        WaitForSingleObject(tmp, ms);
        CloseHandle(tmp)
    }
    

    Dabei haengt die Exaktheit vom Betriebssystem ab.

    Angenommen zwei Tasks(Funktionsaufrufe) passieren "gleichzeitig" (Zeitpunkt t=0)

    Das erklaere mal genauer. Du kannst doch das Starten der Tasks steuern, dann verbiete "gleichzeitig" einfach.

    WaitOnSingleObject ist mir nicht bekannt. (Betriebssystem ist ein QNX in der Version 6.5

    Boah, da krieg ich ja so einen Hals. Warum schiebst du erst jetzt entscheidene Informationen nach. Muss dir alles aus der Nase gezogen werden. Vielleicht beschreibst du mal deine Arbeitsumgebung genauer!

    Dann mach es halt mit pthreads. Ist doch nur eine Simulation, normalerweise steuerst du, was gleichzeitig passiert.



  • War mir ehrlich gesagt nicht bewusst, dass ich entscheidene Informationen zurückgehalten habe, entschuldige.

    Also ich versuch es nochmal genauer zu beschreiben.

    Nehmen wir an, ich habe 2 Tasks die mit einer Periode von 4 Zeiteinheiten wiederholt werden. Beide Tasks brauchen für ihre Berechnung exakt 2 Zeiteinheiten(an dieser Stelle soll in der Simulation die zu schreibende Funktion aufgerufen werden). Beide Tasks werden nun bei einem Schduler registriert, der zu den Zeitpunkten 0,4,8,... beide Tasks aktiviert. Nehmen wir weiterhin an, er teilt nach einem einfachen Schema, den Tasks abwechselnd einen Timeslot von 1 ZE zu. Sprich Task 1 bekommt die Slots (0,1) und (2,3) und Task 2 bekommt die Slots (1,2) und (3,4). Selbst wenn ich davon ausgehe, dass Task 2 das erste mal zum Zeitpunkt t=1 anfängt zu arbeiten und einen Timestamp generiert, würde der Endzeitpunkt bei t=3 sein. Da aber im Intervall (2,3) Task 2 keine CPU Zeit hat, wäre am Ende die Rechenkapazität kleiner als gewollt (1 ZE statt der gewollten 2 ZE).

    Ich selbst hab allerdings keinen Einfluss darauf, wie die Tasks gestartet werden, wie sie ihre Rechenzeit zugeteilt bekommen, bzw. wie und wann sie unterbrochen werden (Sprich prinzipiell kann die Task zu jedem Zeitpunkt unterbrochen werden).

    Ich muss im Endeffekt nur sichstellen, dass die Funktion die ich schreibe, exaxt eine bestimmte Rechenzeit verbraucht, unabhängig davon ob sie unterbrochen wird.

    Zur Umgebung kann ich ansich nicht viel sagen. Das System hat ein Core_i7 Porzessoren mit einem QNX OS in der Version 6.5.



  • Kurz: Was du vorhast, ist nicht moeglich.

    Grund: Ein Prozess weiss normalerweise nicht, dass er unterbrochen wurde.



  • for (int i = 0; i < 100000; i++);

    Damit verbrauchst du immer dieselbe Rechenzeit unabhängig von Unterbrechungen. Man sollte dem Compiler noch sagen, dass er das nicht wegoptimieren soll.

    Die Alternative wäre auf Simulationszeit zu wechseln. Such mal nach Simulationsbibliotheken, da gibt es sowas ähnliches wie Threads (Prozesse), aber du kannst sie exakt steuern (mit sowas wie advance(5) /*es vergehen hier 5 Zeiteinheiten*/; interrupt(process); resume(process); ...). Das funktioniert allerdings mit Modellzeit und nicht mit Rechenzeit, aber um verschiedene Scheduling-Algorithmen zu testen ist es genau das Richtige.


Log in to reply