PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Geschwindigkeitsmessung Prozessor



besa
10.10.2007, 20:40
Hallo zusammen,

ich habe ein kleines Programm geschrieben das eine int Variable in einer while-Schleife hochzählt. Abgebrochen wird über eine getStopwatch < 5000 Bedingung.

Das Ergebniss sind ca. 11500 Zyklen. Bei 8Mhz hätte ich einiges mehr erwartet. Zwar nicht 8000000 * 5 aber doch wesentlich höher als 11500.

Kann mir das jemand erklären?

Gruß

Sascha

Dirk
10.10.2007, 21:04
Hallo Sascha,

das scheint mir auch ein bisschen wenig.
Deine Zählschleife soll also in etwa 5s bis auf 11500 zählen, das würde bedeuten, dass sie 435us für einen Durchlauf braucht, dass wären 3478 Prozessortakte.
Das scheint mir auch viel zu viel!

Bist du sicher, dass deine Integer-Variable nicht mehrfach überläuft?
Setz dir doch eine Variable auf true, wenn erstmals die 32767 erreicht ist. Bleibt die dann false, liegt kein Überlauf vor.

Gruß Dirk

besa
11.10.2007, 19:14
Hallo Dirk,

ich habe zum Zählen eine uint32 Variable verwendet. Die dürfte eigentlich nicht überlaufen. (oder mein MEGA ist megaschnell O:) )

Ich poste mal den Code:



#include "RP6RobotBaseLib.h"

int main(void)
{
initRobotBase();

uint32_t nCounter = 0;

startStopwatch1();
while(getStopwatch1() < 5000)
{
nCounter++;
}

writeString("Gezählte Zyklen:");
writeInteger(nCounter,DEC);

return 0;
}


Ich meine mal gelesen zu haben der Code sollte eigentlich in einem eigenen Bereich abgelegt werden. Falls das so ist bitte ich um ein Tipp wo dieser ist. Ich habe nämlich nichts gefunden. Upload schien mir übertrieben.

Gruß

Sascha

besa
11.10.2007, 19:33
Autsch,

ich glaube ich hab's. Die Funktion writeInteger benötigt einen int16 als Parameter.

Na dann will ich mir doch mal High-Word und Low-Word anschauen.

Gruß

Sascha

Dirk
11.10.2007, 20:20
Hallo Sascha,

bevor du weitere schwierige Tests mit deiner Zählschleife machst:
Wie wäre es, wenn du erst einmal deinen Test umkehrst!

Du setzt die Stopwatch auf 0 und läßt deine Schleife 10000x laufen (Abbruch bei nCounter = 10000). Dann gibst du dir den Stand der Stopwatch aus.

Das gibt dir einen Hinweis, wieviele ms dein Prozessor für die 10000 Schleifendurchläufe braucht.

Gruß Dirk

P.S.: Ich kenne die Antwort schon. Viel Spaß.

radbruch
11.10.2007, 22:01
Hallo

Meiner Meinung nach ist der Ansatz das mit einer Stopwatch zu messen falsch. Der ganze Interruptoverhead ist viel größer als der Code zum Zählen. Überhaupt sollten für solche Highspeed-Messungen die Interrupts gesperrt sein.

Beim RP6 würde ich erst mal alle Interrupts (einzeln von Hand) im jeweiligen Kontrollregister ausschalten, dann einen Timerinterrupt freigeben und den Timer starten. Anschließend Variable hochzählen und mit der Timer-ISR auswerten.

Gruß

mic

besa
16.10.2007, 19:10
Du setzt die Stopwatch auf 0 und läßt deine Schleife 10000x laufen (Abbruch bei nCounter = 10000). Dann gibst du dir den Stand der Stopwatch aus.


@Dirk:

Nach Ausgabe meines High-Words und meines Low-Words habe ich in 5 Sekunden ungefähr 1.5 Millionen durchläufe.

Ein Test mit der Ausgabe der Stopwatch verlief merkwürdig.

Folgenden Code habe ich verwendet:

uint32_t nCounter = 0;

setStopwatch1(0);
startStopwatch1();

writeString("\nZeit1 ");
writeInteger(getStopwatch1(),DEC);

while(nCounter < 1000000)
{
nCounter++;
}


writeString("\nZeit2 ");
writeInteger(getStopwatch1(),DEC);

Unabhängig von der Anzahl der Durchläufe zeigt mir die Ausgabe nur:

Zeit1 1
Zeit2 3

an.

Wird die Schleife vom Compiler wegoptimiert?

@radbruch
Dieser Test mit der Schleife dient nur der Ermittlung eines ungefähren Wertes um ein Gefühl für den RP6 zu bekommen.


Gruß

Sascha

radbruch
16.10.2007, 19:47
Hallo

Aha, dann schau mal wie schnell er ist:


void servo(void)
{
delay=(x+y+z)/10;
pos_x=x*7+470;
pos_y=y*7+480;
pos_z=z*7+490;
cli();
PORTA |= E_INT1; // E_INT1 (Pin8)
while (pos_x--) dummy ^= pos_x;
PORTA &= ~E_INT1;
PORTC |= 1; // SCL (Pin10)
while (pos_y--) dummy ^= pos_y;
PORTC &= ~1;
PORTC |= 2; // SDA (Pin12)
while (pos_z--) dummy ^= pos_z;
PORTC &= ~2;
sei();
sleep(100-delay);
}


Mit diesem Code steuere ich mit dem RP6 die Servos bei meinem Einbein (http://www.youtube.com/watch?v=DuBNTOLDpS8). Es werden Impulse von 0,5-1,5ms erzeugt, das entspricht -90 bis +90 Grad (die Servos streuen etwas). Dafür verwende ich Zählschleifen bei gesperrten Interrupts. Die jeweiligen Zählerwerte setzen sich aus dem Wert für -90 Grad (bei dieser Verzögerung durch die dummy-Zuweisung ca. 470-490 ~ 0,5ms) und dem Wert für die gewünschte Servostellung zusammen. Der Faktor 7 bewirkt dabei, das bei einem Wertebereich von 0-255 das Servo 180 Grad dreht. Daraus kann man dann ableiten, dass die Schleife für 255*7=1785 Durchgänge ca. 1ms braucht (und für 255*7+480=2265 ca. 1,5ms benötigt).

Gruß

mic