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?
Wenn z.B. ich dir konkrete Tipps geben wollte, so würde das nur gehen wenn du mir einen optimierungswürdigen Codebroken vorwirfst...
> 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.
>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...
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?
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.
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
> 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.
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?
> 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.
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 ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.