Forum: Compiler & IDEs Polling / Kommunikation optimieren


von 0undNichtig (Gast)


Lesenswert?

Guten Abend Community!

Ich habe mal eine Frage und zwar möchte ich einen Analog/Digitalwandler 
an einen Atmega64 nutzen.
Das ist ein 2MS ADC mit 8bitigem Parallel Interface. Zur Steuerung 
werden 3 Leitungen genutzt, mit denen man jede Wandlung initialisieren 
muss (macht er leider nicht automatisch). Nun muss ich das natürlich so 
schnell wie möglich machen und entsprechend wohl tunen:-/

Leider ist der qC so voll, dass die PINs auch noch an unterschiedlichen 
Ports liegen.
Und dann auch noch die UND/ODER Verknüpfungen für Setzen/Lesen der 
PIN-Pegel...
Und Schleife fürs warten auf Signale...
Geht das nicht schneller? Nicht dass ich dann wirklich noch mit ASM 
anfangen muss :-(
Gibt es keine Anweisung, damit er sich möglichst viele Register für 
diese eine Funktion leer hält (lieber Stack nutzt) und so die 
Verknüpfungen/Schleifen evtl. schneller werden?

Ich kenne nur REGISTER (Variable wird im Register gehalten, habe aber 
keinen Zähler), STATIC und habe mir auch schon Atmels "efficent C 
coding" durchgelesen, was aber eigentlich zu 99% im MC AVR-Tut (besten 
Dank an der Stelle! :-)) erwähnt wird.

Hat einer ne Idee? Ich weiß, ist n bissel allgemeingültig, gell?

von Ulrich (Gast)


Lesenswert?

Wenn z.B. ich dir konkrete Tipps geben wollte, so würde das nur gehen 
wenn du mir einen optimierungswürdigen Codebroken vorwirfst...

von Karl H. (kbuchegg)


Lesenswert?

> Und dann auch noch die UND/ODER Verknüpfungen für Setzen/Lesen der
> PIN-Pegel...

Mach dir deswegen keine Sorgen. Das optimiert dir der Compiler
alles auf einen einfachen "Set Bit am Port".

> Gibt es keine Anweisung, damit er sich möglichst viele Register für
> diese eine Funktion leer hält (lieber Stack nutzt) und so die
> Verknüpfungen/Schleifen evtl. schneller werden?

Der AVR-gcc macht das eigentlich sehr gut.


von 0undNichtig (Gast)


Lesenswert?

>Mach dir deswegen keine Sorgen. Das optimiert dir der Compiler
>alles auf einen einfachen "Set Bit am Port".

Wenn ich mir die .lss anschaue dann macht er das ja leider gerade nicht 
in jedem Fall :-(
AVRStudio scheint auhc beim disassemblen nicht wirklich toll zu sein, 
Schleifen werden da nicht wirklich verständlich dargestellt...

von Karl H. (kbuchegg)


Lesenswert?

Beispiel?

Optimizer eingeschaltet?

von 0undNichtig (Gast)


Lesenswert?

Kreige ich leider nicht wieder reproduziert, habe schon n bissel mehr an 
dem Code rumgewerkelt.

Es gibt ja in der AVRLibC (stdint.h) auch die FAST Typen, der für mich 
interessante wäre int_fast8_t. Ich konnte aber nirgendwo finden, wieos 
die nun schneller sein sollen?

von Rolf Magnus (Gast)


Lesenswert?

Das hat mit "schneller sein" nichts zu tun. Das sind ISO-C-Typedefs.
int_fast8_t ist der schnellste Integer-Datentyp, der mindestens 8 Bit 
breit ist, nichts weiter. Es ist bei AVR vermutlich einfach ein typedef 
für char.

von 0undNichtig (Gast)


Lesenswert?

Ich hätte mal noch 2 andere Fragen :-)

1. Gibt es eine Datei oder ein Programm, dass einem die Cycles für einen 
bestimmten Codeabschnitt raussucht? Per .lss und OpCode-Table ist dass 
doch immer recht nervig.

2. Wie viel Overhead erzeugen ISRs? Werden dort alle, nur die für die 
AVRLibC Kommunikation oder nur die innerhalb der ISR veränderten 
Register gepusht/popt?

Das ist echt net leicht schneller zu werden... Einige Konstanten scheint 
er weiterhin partout aus dem Flash holen zu wollen grummel

von Karl H. (kbuchegg)


Lesenswert?

> 1. Gibt es eine Datei oder ein Programm, dass einem die Cycles für einen
> bestimmten Codeabschnitt raussucht? Per .lss und OpCode-Table ist dass
> doch immer recht nervig.

AVR Studio im Simulator.
Dort gibt es eine 'Stopuhr'
Du setzt einen Breakpoint auf den Anfang der interessierenden
Sequenz, setzt die Stopuhr zurück. Breakpoint ans Ende der
Sequenz. Programm laufen lassen und bei erreichen des Breakpoints
die 'Stoppuhr' ablesen.

> 2. Wie viel Overhead erzeugen ISRs? Werden dort alle, nur die für die
> AVRLibC Kommunikation oder nur die innerhalb der ISR veränderten
> Register gepusht/popt?

Lass dir vom Compiler ein Assembler Listing erzeugen,
dann weist du es genau.

> Das ist echt net leicht schneller zu werden... Einige Konstanten
> scheint er weiterhin partout aus dem Flash holen zu wollen *grummel*

Wie meinst du das?
Normalerweise haben die meisten Schwierigkeiten dabei, Konstanten
ins Flash zu verlegen. Der umgekehrte Fall ist eher selten.



von 0undNichtig (Gast)


Lesenswert?

Ich meinte das so:
Ich möchte einen PIN zusätzlich an/aus schalten. Wenn ich das in C wie 
gewohnt mache (PORTA&=(1<<PA1) werden ASM 2 Anweisungen erzeugt (IN+OR)

Deshalb lade ich beim Funktionsbeginn den Portzustand in Buffer 
Variablen, die ich per REGISTER in ein Register legen lass und diesen 
Wert schreibe ich dann immer auf den Port zurück. Dadurch wird nur 1 ASM 
Anweisung erzeugt.

An einer Stelle funktioniert das aber nicht:
ADC_CPORT=bufRDlow;
9be:  30 93 65 00   sts  0x0065, r19

Da wird nun ein STS (2 Takte da Flashzugriff) gemacht obwohl die 
Konstante wunderbar in einem Register sein könnte. Wie treibe ich ihm 
das bloß aus?

von Rolf Magnus (Gast)


Lesenswert?

> Ich möchte einen PIN zusätzlich an/aus schalten. Wenn ich das in C wie
> gewohnt mache (PORTA&=(1<<PA1) werden ASM 2 Anweisungen erzeugt (IN+OR)

Das ergibt keinen Sinn. Erstens benutzt du & statt |, zweitens würde ich 
in diesem Fall noch eine dritte Anweisung erwarten, nämlich out, 
drittens macht GCC daraus normalerweise (angenommen, | statt & war 
gemeint) ein sbi PORTA, PA1. Vielleicht Optimierungen aus?

> Deshalb lade ich beim Funktionsbeginn den Portzustand in Buffer
> Variablen, die ich per REGISTER in ein Register legen lass und diesen
> Wert schreibe ich dann immer auf den Port zurück. Dadurch wird nur 1
> ASM Anweisung erzeugt.

Ich würde erwarten, dass in beiden Fällen jeweils nur eine ASM-Anweisung 
erzeugt wird. Im ersten sowieso und im zweiten weil die Variable 
vermutlich komplett wegoptimiert wird und dann dasselbe wie im ersten 
Fall draus wird.

> An einer Stelle funktioniert das aber nicht:
> ADC_CPORT=bufRDlow;
> 9be:  30 93 65 00   sts  0x0065, r19
>
> Da wird nun ein STS (2 Takte da Flashzugriff) gemacht obwohl die
> Konstante wunderbar in einem Register sein könnte.

Was für ein Flashzugriff? Was für eine Konstante? Die angegebene 
Instruktion kopiert den Inhalt von r19 an die Adresse 5 im RAM. Du 
solltest vielleicht erstmal nachschauen, was die ASM-Instruktionen 
eigentlich machen, bevor du einfach irgendwas schlussfolgerst.

von 0undNichtig (Gast)


Lesenswert?

Entschuldige, ich meinte natürlich nicht Flash sondern SRAM, war gestern 
etwas kaputt.

Optimierung steht im MakeFile auf S, das ist doch ausreichend oder muss 
dort 0..3 stehen? Wäre natürlich ärgerlich aber mein Fehler ;-)

von 0undNichtig (Gast)


Lesenswert?

Auch andere Optimierungslevel bringen keine weiteren 
Geschwindigkeitszuwachs.

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.