Forum: Mikrocontroller und Digitale Elektronik Auslastung/Rechenleistung eines µC


von Klopfer (Gast)


Lesenswert?

Hallo!

Jedem ist wohl die Prozessorauslastung unter Windows und Linux bekannt.
Wie kann man sowas auf einem µC realisieren?
Wann weiß ich, dass ein Prozessor voll ausgelastet ist? Wie kann ich das 
messen? Wie bestimme ich eine theoretisch Auslastung über 100%? Und wie 
kann man sowas auf Rechenaufgaben umsetzen? Also für die Berechnung von 
Dem-und-dem habe ich (rechnerisch) eine Auslastung von so-und-soviel 
Prozent?

Danke schon mal!

Gruß
Klopfer

von Teplotaxl X. (t3plot4x1)


Lesenswert?

So nen µC ist immer voll ausgelastet, sofern du ihn nicht in den 
schlafmodus versetzt

von crazy horse (Gast)


Lesenswert?

der PC auch, er verbringt die nicht benötigte Zeit im Lerlaufprozess. Es 
bleibt beiden ja auch nichts weiter übrg, wenn nichts zu tun ist...

von Michael H* (Gast)


Lesenswert?

@mrl33tn3zZ:
nein, das ist blödsinn.

@klopfer:
beschäftige dich mal mit realzeittheoremen - dann sollte das klar 
werden.
auslastung wirst du sinnvoll nur errechnen können, wenn du verschiedene 
tasks hast.
der simpelste fall dafür ist übrigens auch schon ohne "betriebssystem" 
zu bekommen: wenn du einen AVR nur periodisch, interrupt-getriggert 
aktionen durchführen lässt, hast du als auslastung: (rechenzeit aller 
interrupts in einer periode)/(periodenzeit).

von Klopfer (Gast)


Lesenswert?

"Realzeittheorem"!? - Sicher, dass das so heißt?
Google findet keinen einzigen Treffer!

Zu deiner Formel: Da steckt die Variable "Rechenzeit" drin.
Woher weiß ich denn, wie lange die Berechnung von etwas dauert?

von Klopfer (Gast)


Lesenswert?

Einen Timerstand abfragen ist zu ungenau, da bei sehr schnellen 
Berechnungen einen zu großen Einfluss auf die Gesamtzeit hat, da die 
Systemzeit und dessen Abfrage ebenfalls Rechenleistung/-zeit 
beansprucht.

von Michael H* (Gast)


Lesenswert?

mittlerweile heißt es scheinbar "Echtzeit". das findet man in <10s 
raus...

> Einen Timerstand abfragen ist zu ungenau, da bei sehr schnellen
wer schreibt hier etwas von timerständen?

von Klopfer (Gast)


Lesenswert?

Es bleibt noch immer die Frage, wie ich die Rechenzeit in µs 
(Taktzyklen) bestimme.

von Michael H* (Gast)


Lesenswert?

setz einen pin??? simuliers???
man...

von Gast (Gast)


Lesenswert?

Um Auslastung zu erfassen, muss ich "Nichtstun" definieren. Sonst ist 
die Auslastung 100%.
Wenn in meinem Programm eine Endlosschleife läuft, tut die CPU immer 
was. Wenn ich in der Schleife entscheide, ob ich was tun soll, dann muss 
ich erfassen wie lange ich was tue und wie lange ich warte. Es muss also 
eine Zeitbasis geschaffen und ausgewertet werden. Diese Basis könnte ein 
Timer mit hoher Eingangsfrequenz sein. Diesen muss ich dann in der 
Endlosschleife verwalten.
Sowas macht normal das Betriebssystem mit dem Scheduler (-> Wikipedia).

Gruss

von Klopfer (Gast)


Lesenswert?

Reagiere nicht so genervt!

Ich red hier von nem Blackfin, ARM oder nen großen AVR.
Wie soll man das simulieren. Zumal eine Simulation nicht in Echtzeit 
ablaufen würde.

Pin setzten kosten auch wieder einige Taktzyklen. Und dann müsste ich 
das ganze extern (mit nem Oszi) messen.

Ich brauche da Ergebnis aber zur Laufzeit und in mindest µs-Genauigkeit.

von Sebastian B. (mircobolle)


Lesenswert?

Gast wrote:
> Um Auslastung zu erfassen, muss ich "Nichtstun" definieren. Sonst ist
> die Auslastung 100%.
> Wenn in meinem Programm eine Endlosschleife läuft, tut die CPU immer
> was. Wenn ich in der Schleife entscheide, ob ich was tun soll, dann muss
> ich erfassen wie lange ich was tue und wie lange ich warte. Es muss also
> eine Zeitbasis geschaffen und ausgewertet werden. Diese Basis könnte ein
> Timer mit hoher Eingangsfrequenz sein. Diesen muss ich dann in der
> Endlosschleife verwalten.
> Sowas macht normal das Betriebssystem mit dem Scheduler (-> Wikipedia).
>
> Gruss

in meinem system ist die endlosschleife im main() leer.

Mein System läuft im RTC (Takt 1 ms). Ansonsten noch ISRs für I2C, SCI 
und SPI.

Nun kann man einen Pin am Anfang der RTC ISR high setzen und am Ende 
low. Wenn man sich das nun am Oszi anschaut erhält man durch das 
Tastverhältnis high/low die Auslastung (im Mittel zu betrachten).

In meinem System ist dies noch abhängig vom Systemzustand. Aber für eine 
grobe Abschätzung würde ich sagen ist das schon mal iO.

Bei richtigen Echtzeit Betrachtungen brauchst du die Ausführungszeit 
jedes Tasks und die Periodenzeit jedes Taks. Das ganze zeichnet man in 
ein Zeitdiagramm + spoardische Interrupts und macht dann eine 
Worst-Case-Analyse.

von Michael H* (Gast)


Lesenswert?

Klopfer wrote:
> Reagiere nicht so genervt!
och möönsch ^^

> Ich red hier von nem Blackfin, ARM oder nen großen AVR.
immerhin was anständiges ^^
> Wie soll man das simulieren. Zumal eine Simulation nicht in Echtzeit
> ablaufen würde.
warum denn echtzeit? für eine realzeit... ääh... echtzeit-analyse reicht 
eine simulation aus.
wenn ich mich recht erinnere, gab es von cadence da mal ein tool dazu. 
ob das allerdings die modernen rechenarchitekturen kennt, weiß ich 
nicht.

> Pin setzten kosten auch wieder einige Taktzyklen. Und dann müsste ich
> das ganze extern (mit nem Oszi) messen.
richtig. die zeiten zum pin-setzen sind in 2 zeilen zu errechnen, wenn 
du dir den assembler-code und das datenblatt des µC dazu anschaust.

> Ich brauche da Ergebnis aber zur Laufzeit und in mindest µs-Genauigkeit.
sicher? reden wir hier wirklich von einem dynamischen scheduling?

von Noname (Gast)


Lesenswert?

1. Mach dir einen Timer mit 1 msec Takt, in der ISR wird ein Timer 
inkrementiert. Diesen Wert kannst du an beliebiger Stelle im Programm 
abfragen und damit messen, wie lange ein Programmteil brauchte. Damit 
hast du es schon mal auf etwa 1 msec genau.

2. Wenn du es genauer haben willst kannst du noch beim Start und Ende 
der Laufzeitmessung den Wert des Timer Reload Registers mit 
einberechnen, also z.B. Reload Value ist 1000, dann hast du ne Auflösung 
von 1 usec.

von Matthias (Gast)


Lesenswert?

Man kann die Rechenzeit jeder Routine bestimmen, indem man den
Assemblercode analysiert und die Anzahl der benötigten Taktzyklen
bestimmt. Mit dem jeweiligen uC Takt kann man daraus die Rechenzeit 
bestimmen. Eine experimentelle Methode ist das Setzen eines Portpins
zu Beginn einer Routine und das Löschen am Ende.

Das hat allerdings den Nachteil, dass die Zeit, die für 
Registersicherungen beim Funktionseintritt nicht mit in die Messung 
einfließt.
(das kann bei ISRs nützlich sein - aber Achtung wegen der Portzugriffe! 
Die sollten Atomar sein!)

In einer Hauptprogrammschleife kann man die Zykluszeit (Rechenzeitbedarf 
aller "Tasks" bestimmen - wenn man das näherungsweise als kooperatives 
Multitasking betrachtet ) Messen (Port toggeln).

Diese Methode ist allerdings ein Schätzeisen, wenn der Rechenzeitbedarf
von den Daten abhängt. Beispiel AVR und Multiplikation oder allgem. 
Division, wenn keine HW Unterstützung vorhanden ist. Diese Stellen im 
Code muss man kennen und eine Abschätzung auf anderem Weg (worst case -> 
Taktzyklen aus Assemblercode, etc.) bestimmen.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Wenn der Debugger es erlaubt: in zufälligen Abständen den Program 
Counter auslesen, dazugehörige Funktion/Modul/Aufgabe bestimmen, 
Histogramm plotten.

von Juergen (Gast)


Lesenswert?

> Ich brauche da Ergebnis aber zur Laufzeit und in mindest µs-Genauigkeit.

Was ist denn der Sinn der Uebung?

Juergen

von Michael H* (Gast)


Lesenswert?

Noname wrote:
> 1. Mach dir einen Timer mit 1 msec Takt, in der ISR wird ein Timer
> inkrementiert. Diesen Wert kannst du an beliebiger Stelle im Programm
> abfragen und damit messen, wie lange ein Programmteil brauchte. Damit
> hast du es schon mal auf etwa 1 msec genau.
nein! abtasttheorem... außerdem ist das eine methode zu fuß über den 
holzweg neben der autobahn.

wenn du dynamische rechenzeiten zur laufzeit bestimmen willst, würde ich 
dir zu einem extra task - falls die voraussetzungen dafür gegeben sind - 
oder zu einem extra controller, der dir allein das scheduling macht, 
raten. ein extra controller kann wunder wirken, wenn man mit sog 
dead-locks zu kämpfen hat.

von Klugscheisser (Gast)


Lesenswert?

Benedikt K. hatte da mal eine recht pragmatische Methode. Leider finde 
ich den Thread nicht mehr. War aber hier in einem der Foren.

Wenn ich mich recht entsinne, hatte er da einen Portpin gesetzt und den 
immer gelöscht, sobald der uC was tun sollte. Dann wieder gesetzt, wenn 
er irgendwo in einer Leerschleife rumhing.
Hoffe Benedikt K. liest das hier und kann das nochmal genauer erklären. 
Jedenfalls erhielt man so eine Art PWM aus deren Tastgrad man auf die 
Auslastung schliessen konnte.

von Klaus (Gast)


Lesenswert?

@ Matthias

>Man kann die Rechenzeit jeder Routine bestimmen, indem man den
>Assemblercode analysiert und die Anzahl der benötigten Taktzyklen
>bestimmt.

... diese Aussage ist schlicht weg falsch!!!

Keiner kann die tatsächliche Anzahl von benötigten Takten bestimmen,
wenn nur ein einziger bedingter Sprung drin ist! Man müsste zu
jeder Zeit den Zustand des µCs kennen!

Klaus

von Klausi (Gast)


Lesenswert?

sorry, sehe gerade, da ist noch ein Klaus unterwegs.
Von jetzt an Klausi.

von Matthias L. (Gast)


Lesenswert?

>Ich brauche da Ergebnis aber zur Laufzeit und in mindest µs-Genauigkeit.

Was hast du denn vor?

von Analog (Gast)


Lesenswert?

Wenn von Prozessorauslastung die Rede ist, dann ist es schlicht und 
einfach bei den AVRs so, daß pro Taktperiode ein Befehl (RISC, ja es 
gibt auch Befehle mit 2 Taktzyklen....) ausgeführt wird. Es ist völlig 
wurscht ob das ein NOP, ADD , SUB oder MOV ist. Das heißt er tut immer 
was und ist völlig ausgelastet. Der Fehler ist hier von Auslastung zu 
sprechen. Will man die Rechenleistung messen braucht man eine Referenz 
z.B. Mikrocontroller XY mit TAKT XY und vergleicht die verstrichenen 
Zeiten pro Aufgabe.

von Noname (Gast)


Lesenswert?

Noname wrote:
> 1. Mach dir einen Timer mit 1 msec Takt, in der ISR wird ein Timer
> inkrementiert. Diesen Wert kannst du an beliebiger Stelle im Programm
> abfragen und damit messen, wie lange ein Programmteil brauchte. Damit
> hast du es schon mal auf etwa 1 msec genau.
nein! abtasttheorem... außerdem ist das eine methode zu fuß über den
holzweg neben der autobahn.


Deswegen steht da ja auch ein "ETWA", schon klar das das nur ne 
ungefähre Angabe ist ;-).

"außerdem ist das eine methode zu fuß über den holzweg neben der 
autobahn."
Wieso das? Was glaubst du denn wie ein Embedded OS das macht?

von Klausi (Gast)


Lesenswert?

.. Mal(x) mit zuerwartender Häufigkeit der Aufgaben pro Zeiteinheit.

von Matthias L. (Gast)


Lesenswert?

>nein! abtasttheorem... außerdem ist..

Das Abtasttheorem (fsampling/2 > fsignal) hat damit garnichts zutun.
Das kommt zur Anwendung, wenn es um Frequenzen und deren Rekonstruktion 
geht.

Die hier vorgeschlagene Methode nutzt quasi jeder Frequenzzähler.
Diese haben immer einen Fehler von -1Takten...

Unter der Annahme, dass das Abnehmen des Zählerstandes selbst keine Zeit 
benötigt, ist dieses Verfahren genau genug.

von Sebastian B. (mircobolle)


Lesenswert?

Beim Lesen des Threads ist mir eine alternative Idee gekommen, wie man 
die Auswertung der Systemauslastung statt per Pin-Toggeln mit SW lösen 
kann.

Es ist natürlich stark davon abhängig wie das System aufgebaut ist.
Aber ich gehe nun von einem "Echtzeit-System" aus, welches seine 
Task-Abarbeitung in der RTC ISR ausführt. Der Takt der RTC ISR ist 1 ms.

Nun muss man natürlich etwas Overhead spendieren um eine solche 
Systemlast Messung durchführen zu können.

Idee: (in Pseudo Code)
1
_interrupt ISR_RTC (void){
2
   
3
   static unsigned short s_load_buffer[10]; 
4
   static unsigned char s_load_index = 0;
5
  
6
   Timer_1_Reset (); /* startet Timer  1 */
7
8
   /* Task - Abarbeitung */
9
   
10
   /* Last Messung */
11
   s_load_buffer[s_load_index] = Timer_1_Get_Ticks();
12
13
  /* ... */
14
   
15
}

Mit etwas Overhead könnte man also einen Extra Hardware Timer starten, 
der ab einem gewissen Punkt anfängt zu laufen und an an einem bestimmten 
Punkt abgefragt wird. Anhand der vergangenen Ticks lässt sich die 
vergangene Zeit ermitteln.

dann wäre:
Auslastung = vergangene_Zeit / RTC_Perioden_Dauer;

Diesen Wert könnte man mitteln etc. und dann per RS232 abfragen, somit 
könntest du tatsächlich die Systemlast ermitteln und abfragen.


Was hier natürlich nicht berücksichtigt wird sind sporadisch auftretende 
Interrupts. Hier könnte man so vorgehen, dass man die Laufzeit der ISRs 
separat misst und dann per Offseft auf die gemessene Last addiert. Damit 
hätte man dann automatisch eine "Worst-Case" Betrachtung. Liegt der Wert 
dann unter einer bestimmten Schwelle... ca. 70 % dann hat dein System 
noch etwas Luft nach oben.

Grüsse aus der Pfalz ;-)

von Klopfer (Gast)


Lesenswert?

Naja, um was es genau bei der Sache geht darf ich nicht sagen.

Der Prozessor bekommt halt permanent neue Aufgaben zumindest zur 
Verfügung gestellt. Ein Management soll nun überwachen, dass der 
Prozessor nicht mehr Aufgaben "annehmen"/"übernehmen" soll, wie er 
berechnen kann. Und zwar berechnen, ohne dass die Ergebnisse der 
einzelnen Aufgaben nicht länger als eine bestimmte Zeit brauchen. Also 
deterministisch sind.
Was im übrigen auch als Echtzeit ebszeichnet wird, denn Echtzeit heiß 
nur, dass das Ergebnis innerhalb eines definierten Zeitfensters 
vorliegt. Das Zeitfenster kann Stunden oder gar Tage sein, hier geht es 
stellenweise in den µs-Bereich.

Ich brauche also eine Methode/Task/Thread, mit der ich die "freie" 
Rechenleistung bestimmen kann.

von Matthias (Gast)


Lesenswert?

>@ Matthias

>>Man kann die Rechenzeit jeder Routine bestimmen, indem man den
>>Assemblercode analysiert und die Anzahl der benötigten Taktzyklen
>>bestimmt.

>>... diese Aussage ist schlicht weg falsch!!!

>Keiner kann die tatsächliche Anzahl von benötigten Takten bestimmen,
>wenn nur ein einziger bedingter Sprung drin ist! Man müsste zu
>jeder Zeit den Zustand des µCs kennen!

Aber man kann eine "worst case"<->"best-case" Abschätzung machen.
Ob das jetzt 20 Zyklen mehr oder weniger sind ist sowieso meistens egal.
Aber ein Programmierer kennt sein Programm normalerweise so gut, dass
er eine Abschätzung treffen kann. Ausserdem, wenn nur ein oder zwei
Sprünge drin sind (was bei "Eier-Loops" der Falls ist) dann kann man die 
Anzahl der Zyklen schon genau bestimmen.


>>... diese Aussage ist schlicht weg falsch!!!
Ist ebenfalls falsch! Richtig wäre, dass man bei bedingten Sprüngen es 
nicht mehr genau kann, aber trotzdem noch gut abschätzen! ;-)

von Peter D. (peda)


Lesenswert?

Klaus wrote:
> Keiner kann die tatsächliche Anzahl von benötigten Takten bestimmen,
> wenn nur ein einziger bedingter Sprung drin ist! Man müsste zu
> jeder Zeit den Zustand des µCs kennen!

Und auch diese Aussage ist schlicht weg falsch!!!

Natürlich geht das, PIC-Programmierer machen das sehr häufig.

Ich hab sowas schonmal gesehen, ein PIC-Programm auf den Zyklus genau, 
ganz ohne Interrupts.
Der Trick ist ganz einfach, sobald ein bedingter Sprung kommt, wird der 
kürzere Zweig mit NOPs aufgefüllt, bis er gleich lange dauert. Damit hat 
diese Routine immer eine konstante Laufzeit.
Geht natürlich nur mit Assemblerprogrammierung, was ja beim PIC die 
Regel ist.
Natürlich ist ein solcher Programmierstil äußerst zeitaufwendig.


Peter

von Chris S. (schris)


Lesenswert?

Mach oder benutz einen Systemtimer, rechne in Ticks.
Das kann eine 32Khz timer sein, wie auch ein 1ms oder auch 6ms timer,
als Beispiel.

Normalerweise wird das dann so gemacht, daß die Proceduren in Slices
alloziert werden, also ein Slice sind X Ticks. Z.B. 1 Slice sind 64 
Ticks.
Wenn ein Slice frei ist, dann kann die Procedure angefordert werden.
Ist die Prozedur fertig, dann wird in die Yield Prozedure gesprungen.
Diese kann dann je nach verfügbaren Ticks verschiedene anstehende 
Systemaufgaben machen. In Yield kann auch die noch freien Ticks 
aufsummiert
werden, und so der Leerlauf, sprich die Auslastung gemessen werden.

von crazy horse (Gast)


Lesenswert?

Hm, ich glaube, endgültig und beliebig fein wird sich das nicht 
bestimmen lassen können.
Die Laufzeit vieler Routinen ist auch von den (variablen) 
Eingangsparametern abhängig.
Oder man muss wirklich jede Aktion auf gleiche Laufzeit trimmen - dann 
hätte man zuverlässige Vorhersagen, insgesamt aber geringere 
Performance.
Könnte schon Anwendungen dafür geben.
Einfacher ist offensichtlich der andere Weg - mehr Rechenleistung zur 
Verfügung zustellen, als im worst-case benötigt wird und den Überschuss 
zu vertrödeln.

von Chris S. (schris)


Lesenswert?

Achso, du willst ARM, Blackfin, AVR32 verwenden. Dann verwende doch
ein RTOS. Das kann dir auch die Auslastung zur Verfügung stellen,
arbeitet jedoch meistens mit dem oben skizzierten System.

von Klopfer (Gast)


Lesenswert?

Über ein OS kann ich (noch) keine Aussage machen. Ob überhaupt eins zum 
Einsatz kommt, oder nicht. Und wenn ja welches. Das liegt nicht in 
meiner Macht. Aber so wie ich das mitbekommen habe ist hier Linux im 
Gespräch.

mir grauts jetzt schon davor, denn von Linux hab erst recht keine 
Ahnung.

von Fan (Gast)


Lesenswert?

Dann nimm doch ein RTOS von Segger, das arbeitet nach dem Prinzip wie 
oben von Noname beschrieben und liefert dir automatisch die Auslastung. 
Gibt sogar ein PC Tool, ich glaub embOSView heißt das, was dir die 
Auslastung sogar noch gleich graphisch darstellt, einfacher kannst du es 
nicht haben.

von Dino S. (Gast)


Lesenswert?

>Was ist denn der Sinn der Uebung?
Spielverderber :-)

>Naja, um was es genau bei der Sache geht darf ich nicht sagen.
Bravo!
Ich sage Knecht Ruprecht Bescheid.

von P. S. (Gast)


Lesenswert?

Wahrscheinlich verstehe ich wieder nix... aber wo ist das Problem in der 
Hauptschleife einfach nur eine Variable hoch zu zaehlen und das mit 
einem Interrupt jede Sekunde abzufragen (und zu loeschen)? Die freie 
Rechenzeit ist der maximal erreichbare Zaehlerstand / den tatsaechlich 
erreichten Zaehlerstand.

von Klopfer (Gast)


Lesenswert?

Da stellt sich halt die Frage wie Rechenintensiv das Hochzählen und 
Interrupt-gesteuerte Überprüfen des Zählerstandes ist und in wie weit 
man es dann in Relation mit der erforderlichen Rechenzeit der ganzen 
anderen Aufgaben dauert....

von P. S. (Gast)


Lesenswert?

Tja, ein bisschen was wirst du fuer dein Gehalt auch noch machen 
muessen.

von Klaus (Gast)


Lesenswert?

Ich frage mich gerade, ob es echt um eine "Echtzeit-Anwendung" geht, 
oder ob der OP einfach das programmieren am PC gewohnt ist und nun auf 
nem Mikrocontroller nach einem vergleichbarem Maß sucht, um 
festzustellen, wieviele Ressourcen er schon verbraucht hat.

von gast (Gast)


Lesenswert?

!! Achtung kein sinnvoller Vorschlag !!

Nimm einen Analogen Auslastungsanzeige:
Immer wenn was sinnvolles getan wird Pin einschalten ansonsten 
ausschalten. Dann ein RC-Glied dran und daran ein analoges Voltmeter...
sieht bestimmt cool aus ;)

von Matthias (Gast)


Lesenswert?

>!! Achtung kein sinnvoller Vorschlag !!

Warum nicht Sinvoll? Wenn man das RC passend dimensioniert hat das 
ungefähr den gleichen Sinn, wie mit nem Oszi die Zeit zu messen. Ist 
halt ein
Schätzeisen, aber gar nicht so dumm ;-)

von Arc N. (arc)


Lesenswert?

Klopfer wrote:
> Naja, um was es genau bei der Sache geht darf ich nicht sagen.
>
> Der Prozessor bekommt halt permanent neue Aufgaben zumindest zur
> Verfügung gestellt. Ein Management soll nun überwachen, dass der
> Prozessor nicht mehr Aufgaben "annehmen"/"übernehmen" soll, wie er
> berechnen kann. Und zwar berechnen, ohne dass die Ergebnisse der
> einzelnen Aufgaben nicht länger als eine bestimmte Zeit brauchen. Also
> deterministisch sind.
i = Periodisches Ereignis
m = Anzahl der periodischen Ereignisse
C_i = benötigte CPU-Zeit in Sekunden
P_i = Periode des Ereignisses i

Wenn das erfüllt ist, ist das System schedulbar.
Algorithmen für das Scheduling wären z.B.:
Statisch: Rate Monotonic Scheduling, bei diesem Verfahren ist die 
maximale Auslastung für m > 1 kleiner 100 %, genauer: m * (2^(1/m) - 1)
Dynamisch: Earliest Deadline First Scheduling, Auslastung bis zu 100 %

> Ich brauche also eine Methode/Task/Thread, mit der ich die "freie"
> Rechenleistung bestimmen kann.

Leerlaufthread: Kein weiterer Thread im System: n Durchläufe pro 
Sekunde,
weitere Threads im System: m Durchläufe -> m/n = freie Rechenleistung

von Morin (Gast)


Lesenswert?

> Der Prozessor bekommt halt permanent neue Aufgaben zumindest zur
> Verfügung gestellt. Ein Management soll nun überwachen, dass der
> Prozessor nicht mehr Aufgaben "annehmen"/"übernehmen" soll, wie er
> berechnen kann. Und zwar berechnen, ohne dass die Ergebnisse der
> einzelnen Aufgaben nicht länger als eine bestimmte Zeit brauchen. Also
> deterministisch sind.
> Was im übrigen auch als Echtzeit ebszeichnet wird, denn Echtzeit heiß
> nur, dass das Ergebnis innerhalb eines definierten Zeitfensters
> vorliegt. Das Zeitfenster kann Stunden oder gar Tage sein, hier geht es
> stellenweise in den µs-Bereich.
>
> Ich brauche also eine Methode/Task/Thread, mit der ich die "freie"
> Rechenleistung bestimmen kann.

Ein solcher Task ist immer ungenau, weil das Ergebnis eben mit den 
Eingangsdaten schwankt. Der misst nur, was "gerade jetzt" noch an 
Rechenpower frei ist, aber die schon laufenden Prozesse können im 
nächsten Moment schon das doppelte an Rechenpower brauchen. Damit 
bekommst du es vielleicht ungefährt hin, aber du hast keine Garantie, 
dass der Prozessor nicht doch irgendwann mal "überfordert" wird, ganz 
einfach weil die Messung der momentanen Auslastung nicht präzise ist.

Was du brauchst ist die max. benötigte Rechenzeit der schon laufenden 
Aufgaben, aber die bekommst du nicht durch Messen. Die rechnest du 
besser aus (worst-case-Abschätzung). Dann berechnest du, was der 
Prozessor max. leisten kann (Verwaltung mit eingerechnet) und vermerkst 
im laufenden Betrieb, was noch geht.

> Aber so wie ich das mitbekommen habe ist hier Linux im
> Gespräch.
>
> mir grauts jetzt schon davor, denn von Linux hab erst recht keine
> Ahnung.

Dann freu dich schonmal darauf, die worst-case-Abschätzung für den 
Linuxcode zu machen :)

von Klausi (Gast)


Lesenswert?

hey Peter Dannegger (peda)

>> Keiner kann die tatsächliche Anzahl von benötigten Takten bestimmen,
>> wenn nur ein einziger bedingter Sprung drin ist! Man müsste zu
>> jeder Zeit den Zustand des µCs kennen!

>> Und auch diese Aussage ist schlicht weg falsch!!!

>Der Trick ist ganz einfach, sobald ein bedingter Sprung kommt, wird der
>kürzere Zweig mit NOPs aufgefüllt, bis er gleich lange dauert. Damit hat
>diese Routine immer eine konstante Laufzeit.

wer macht den sowas? Das ist das Perverseste was ich hier bis jetzt
gelesen habe!!!

Klaus

von Michael U. (amiga)


Lesenswert?

Hallo,

z.B. Leute, die ein Videosignal in Software auf einem AVR erzeugen oder 
Leute, die auf einem Mega16 einen 6502 Zyklengenau emulieren wollen...

Solche Leute sind so pervers.

PS: Du hast ähnliches noch nie programmiert, vermute ich mal.
PPS: früher hab ich das auf dem C64 so gemacht, weil man ja unbedingt 
den seitlichen Rahmen des Videocontrollers abschalten wollte, damit die 
Sprites dort zu sehen waren. Das hatten die Entwickler aber nicht 
eingeplant. ;)

Gruß aus Berlin
Michael

von crazy horse (Gast)


Lesenswert?

richtig, dafür gibts schon Anwendungen.

von Moritz E. (devmo)


Lesenswert?

Klaus wrote:

> ... diese Aussage ist schlicht weg falsch!!!
>
> Keiner kann die tatsächliche Anzahl von benötigten Takten bestimmen,
> wenn nur ein einziger bedingter Sprung drin ist! Man müsste zu
> jeder Zeit den Zustand des µCs kennen!
>
> Klaus

Diese Aussage ist schlicht weg falsch!!!

Der uC ist deterministisches System. Mann muss nichtmal den ganzen 
Zustand kennen (den man aber sehr wohl auf grund Determinismus fast 
vollständig kennen kann), sondern nur die Zustände/Bits von denen 
Sprünge abhängen. Da die allermeißten Sprünge von boolschen Zuständen 
abhängen, ist das sogar sehr überschaubar, man muss einfach nur alle 
Möglichkeiten durchrechnen. Falls z.B. im Fall variabler Zählschleifen 
oder vieler Abhängigkeiten die mögliche Zustandsmenge zu groß wird lässt 
sich meißtens immer noch Worst und Best-Case angeben.

von Moritz E. (devmo)


Lesenswert?

Ich habe in meinem Programm auch soetwas einbauen wollen.

Ausgehend von einem Programm was als Endlos-Main Schleife aufgebaut ist, 
aus welcher heraus die verschiedenen Tasks bei Bedarf (!) z.b. durch 
Flags signalisiert aufgerufen werden. Denn es muss ja der Fall Möglich 
sein, das beim Nichtstun auch kein Task aufgerufen wird.

Mein erster Ansatz war der mit dem Toggle-Pin:

Jeweils zu Anfang jedes Tasks der die unterste Main-Ebene verlässt, 
ebenso Anfangs jeden Interrupts, wird Pin High gesetzt. Falls Interrupt 
bereits auf einen High-Pin trifft, wird ein Flag gesetzt, das am Ende 
des Interrupts verhindert, den High-Pin zu löschen obwohl der Main-Task 
ja noch läuft.
Am Ende jedes Tasks, also vor dem ret zu main, sowie am Ende jedes 
Interrupts (hier wie oben angegeben nur bedingt) wird Pin auf Low 
gesetzt.

Mein zweiter Ansatz kostet mehr Rechenzeit, lässt aber Zeitmessung jedes 
Tasks einzeln und auch die Idle und Busyzeitmessung insgesammt zu:

Wie oben wird jeweils zu Anfang von Task und Interrupt der Wert eines 
kontinuierlich hochzählenden Systemtimers (ein Hardware-Timer mit 
niedrigem Preskaling, sowie Software-Erweiterung auf über 16 bit, bzw 
Überlauferkennung) gespeichert, für jeden Task/Interrupt in einer 
eigenen Variable. Außerdem setzt der Task ein Flag das laufende Messung 
anzeigt

Trifft ein Task/IRQ auf gesetzte Flags anderer Tasks/IRQs heißt das, das 
ersterer die Laufzeit der letzteren unterbricht, und deren Laufzeit 
verfälscht. Um die Laufzeit für die unterbrochenen Tasks zu korrigieren, 
müssen alle unterbrochenen Tasks als am Ende bei ihrer 
Laufzeitbestimmtung ebenfalls die Laufzeiten der Tasks abziehen, die sie 
unterbrochen haben. Dazu hat jeder Task ebenfalls eine Variable, in der 
die abzuziehenden Laufzeiten aller ihn unterbrechenden Tasks aufaddiert 
werden. Jeder Task muss als am Ende nach Bestimmtung seiner eigenen 
Laufzeit, diese zu den Korrektur-Variablen aller laufenden von ihm 
unterbrochenen Tasks hinzuaddieren.

Will man nur die Systemzeiten messen, aber nicht Tasks einzeln, reicht 
natürlich die Zeitnahme von Start und Endmarken bei allen Tasks und 
IRQs, die die Mainschleife verlassen.

Um das ganze zu optimieren nutzt man vielleicht den Input-Capture 
Interrupt zur Zeitmarken-Name, (der sich allerdings glaube ich nicht 
softwaremäßig auslösen lässt).

Ein regelmäßiger Timer muss außerdem aus den den angesammelten 
Laufzeiten die Ausleistung bestimmen und diese zurücksetzen.


Von Softtimern die von Timerticks getriggert Laufzeiten direkt messen 
halte ich nichts, da die Zeitauflösung zu grob wird. Alternativ kann man 
aber einen Hardwaretimer Anfangs jeden Tasks reseten, nachdem der 
Timerstand des unterbrochenen Tasks zwischengespeichert wurde. Am Ende 
resettet der unterbrechende Task wieder und addiert den 
zwischengespeicherten Timerstand des unterbrochenen Timers zu dessen 
Laufzeit-Variable. Der unterbrochende Task addiert dann am Ende den 
Timerstand ebenfalls auf seine Laufzeitvariable.

Da bei diesen Ansätzen immer ein niedrig oder garnicht preskaled 
Hardwaretimer genutzt wird erreicht man echte Cycle-Auflösung.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.