Tachesacht, da ich die ganze Zeit auf ner long mit Überläufen zu kämpfen habe, dachte ich mir ich spendiere meinem Atmega2561 einfach nen 40Bit Datentyp anstelle der 32Bit des longs. Dann kam eine Weile Grübelei und jetzt bin ich auf dem Stand das ich da ja im Prinzip dem Teil nen neuen Assembler Befehl beibringen müsste. Sprich einem Assembler Befehl Maschinencode zuordnen?! Wollte deswegen mal rumfragen ob es da auch ne einfachere Variante gibt an die ich gerade nicht denke bzw. ob mir jemand nen Tipp oder Lektüre zum beibringen geben kann?! Wäre großartig! Danke schonmal im Vorraus, Icke_Wa
Icke_Wa schrieb: > im Prinzip dem Teil nen neuen > Assembler Befehl beibringen müsste Nennt man Funktion oder Unterprogramm
Ähem, Atmega2561? Seit wann kann der auf Assemblerebene denn mit 32Bit-Daten umgehen? In welcher Sprache programmierst Du? Assembler zu 99,99% nicht... Such dir für diese Sprache eine entsprechende Mathebibliothek.
Icke_Wa schrieb: > ob mir jemand nen Tipp warum nimmst Du nicht einfach int64_t als Datentyp? Gruß Anja
Vieleicht liegen die Überläufe nur an einer ungeschickten Aneinanderreihung der Operationen. Was willst du ausrechnen? Wie sieht dazu dein Code aus? Wie ist der Wertebereich der Variablen?
Nene ich programmiere das Ding braf in C, aber beim grübeln hab ich den Ratschlag meiner Mathelehrerin vergessen "Denk nicht immer so kompliziert!" Mathebibliothek klingt ganz gut. Durchstöber gleich mal die einfache Mathe library. Wie schauts sonst aus mit structs wo man selber Bits zuweisen kann? Hab da hier gerade was gefunden. Das klang irgendwie auch ganz vernünftig. www.mikrocontroller.net/topic/148581 nen 64er Int dauert zu lange. Ich bin in der Bearbeitungszeit ganz gut limitiert und 64Bit dauern zu lange Gerechnet wird da einiges. Das Problem ist, dass ich einen Wertebereich von 2Vorkommastellen und bis zu 7Nachkommastellen abdecken muss. Wenn ich das so skaliere dass ich da nichts verliere, werden die Zahlen einfach so riesig, dass bei der erst besten Multiplikation schon mein signed long überläuft. An ungünstigen Programmablauf kann ich da irgendwie nicht so richtig glauben. Der Zahlenbereich ist einfach zu krass.
Icke_Wa schrieb: > nen 64er Int dauert zu lange. Ich bin in der Bearbeitungszeit ganz gut > limitiert und 64Bit dauern zu lange Ja, die original 64Bit des AVR-GCC sind ein Graus. Man kann sie aber einfach ersetzen, dann gehts viel schneller und auch viel kleiner: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=113673 Peter
Hm das klingt ja schonmal mehr als einfach nur perfekt. Wenn ich dadurch im zeitlichen Rahmen trotz 64BIt wäre, wäre das perfekt ... nur komm ich mir schon wieder so dumm vor, dass ich mich schon wieder heulend in die Ecke verkriechen, und über meine Zukunft nachdenken könnte. Wie füge ich den ein .s file hinzu? in deinem testfile z.B. kommt ja sowas wie nen include nich vor und wenn ich die File einfach in irgend nen Ordnerschupse weiß der Compiler ja immernoch nich dass das Ding existiert. Danke für die Hilfe, aber ich brauch noch mehr ;)
Icke_Wa schrieb: > Wie füge ich > den ein .s file hinzu? Linke Seite unter Source Files markieren und dann rechte Maustaste. Dann Add Existing Source File.
Hallo, ich habe dazu hier etwas geschrieben: Beitrag "Re: Stack Überschreiber beim Rechnen mit uint64_t" Die .S müssen nur Compilert werden und dann geninkt. Zum verwenden einfach den Datetype uint64_t verwenden. Matthias Hopf (mshopf) hat auch noch welche für 64bit=64bit*32bit und 64bit=64bit/32bit geschrieben. Beitrag "Reziproker Frequenzzähler+ Optimierte 64bit uint Routinen" Ich habe für diese Projekt noch eine schellere mul64_32 Variante mit MUL, die nur 177 Ticks benötigt, eingebunden.
hm also im Prinzip einfach die Datei zu dem anderen ins Projekt werfen? Dem Vertrau ich irgendwie nicht. Da hab ich jetzt so nen graues Fenster wie als ob ich was zum drauf rumklicken für Windows schreiben wollen würde. Ist aber glaube ich eh so ne Sache mit der Nutzung dieses Codes. Mache grade nen Praktikum und da sollte ich vielleicht nichts reintippern für was die Firma später wegen copyright und plagiat bla bla auf die Finger bekommt...
Für einen Frequenzmesser ist eine schnelle Rechnung unnötig. Man will ja keinen Augenkrebs kriegen von dem ständigen Geflackere. Eine Anzeigerate von 2..5 Meßwerten/s ist ergonomisch. Wichtiger ist da eher die Codeeinsparung von ~7kB. Damit paßt der Frequenzmesser bequem in den ATtiny2313. Peter
Nochma ne Zwischenfrage bevor ich mir weiter dir Birne darüber zerbreche. Peter meinte der standart AVR-GCC compiler wäre da nicht so fit. Gilt das auch für den AVR IAR C/C++ Compiler??? Den benutz ick nämlich hier :/
Hallo Peter, ja richtig, deshalb verwende ich bei diesem Projekt [1] auch eine Messzeit (Torzeit) von 0,5 - 0,75 Sekunden. Deine 64Bit-Lib hat bei mir den Anstoß gegeben, die Ausführungszeiten der verschiedene 64Bit-Libs und der 64_32Bit Routinen zu untersuchen und ich hatte mir dafür eine Testumgebung [2] programmiert. So war es für mich als mathematisch geprägter Programmierer sehr schön zu sehen, was wie schnell funktioniert. Einzug gefunden habe diese Erkenntnisse in der Berechnung der Frequenz Tuning Word (ftw) bei verschiedenen DDS Bausteinen: AD9834, AD9851 und AD9951. Links [1] Beitrag "Reziproker Frequenzzähler+ Optimierte 64bit uint Routinen" [2] Beitrag "Re: Stack Überschreiber beim Rechnen mit uint64_t"
Hallo Icke_Wa , es ist nicht der avr gcc Compiler, sondern die 64Bit Bibliothek, die wir mit dem Assembler 64Bit-Lib ersetzen ! Zum /AVR IAR C/C++ Compiler/ kann ich nichts beitragen, habe nur noch einen Keil C51 da.
Icke_Wa schrieb: > Gilt das auch für den AVR IAR C/C++ Compiler??? Nein, auf keinen Fall. Meine Assemblerdatei läuft nur mit dem AVR-GCC. Sie benutzt dessen Registerzuweisung und Funktionsnamen. Peter
hm gut zu wissen. Dann kann ich mir die Frage ja spahren warum ich das auf biegen und brechen nicht hinbekomme :P Stellt sich nur die Frage nach der Alternative...
Icke_Wa schrieb: > Stellt sich nur die Frage > nach der Alternative... Hast Du überhaupt festgestellt, daß beim IAR 64Bit zu langsam ist und wie? Was mußt Du berechnen und wie schnell? Peter
Jop dasses zu langsam ist habe ich bereits festgestellt. Ich berechne ne Regelschleife nach Zustandsraum. Sprich schön lecker Matritzenmultiplikation. Um das ganze durchzurechnen brauche ich 6ms, darf aber nur 4,4ms brauchen. Habe aber gerade das ok go bekommen dein Dingsie da durchzuverstehen und es für den IAR umzuwurschteln. Jetzt heisst es Assemblercodes googeln und das Hirn auf Maraton schicken :P
Achso das mit dem Wie ist eigentlich ne gute Frage. Da hab ich mir noch nicht wirklich ne Platte drum gemacht :/ Meinste den kompilierten Assemblercode mal anschauen wär keien schlechte Idee oder wat?
Hallo Icke_Wa, /Um das ganze durchzurechnen brauche ich 6ms, darf aber nur 4,4ms brauchen./ Du alle alle Optimierungen und Vereinfachungen durchgeführt hast, könnte man noch den µP höher Takten, so würde das Programm auch schneller sein. Manchmal kann man auch kleine Ergebniswerte, bzw. deren Berechnung weglassen und durch eine Fehlerabschätzung ersetzen. Wie schnell läuft die CPU Atmega2561 ?
Morgen alle zusammen. Wie schnell die ist weiß ich ehrlich gesagt garnichtmal. Glaube die rennt mit 14MHz. Höher Takten ist keine Option. Das Ding geht in die Medizintechnik. Die Spring mir im Dreieck mit der Idee :P. Hoffe mal das Peters angepasstes Dingen dann funktioniert und ausreicht.
Icke_Wa schrieb: > Hoffe mal das Peters angepasstes Dingen dann funktioniert und ausreicht. Da muß ich Dich enttäuschen. Die Routine ist auf Codegröße optimiert, nicht auf Laufzeit. Die Laufzeit ist zwar auch schneller als die AVR-GCC Lib, aber der IAR wird bestimmt besser optimiert sein. Peter
Hm ... das wäre natürlich Schade. Aber ich hätte da trotzdem noch nen paar Verständnissfragen. Ich raffe noch nicht so ganz wie der Linker überhaupt weiß dass er jetzt dein File nehmen soll und nicht die Standartvariante. Wird das ganze durch die Variable __umoddi3 aufgerufen? Wie kann es dann sein, dass keine Mehrdeutigkeit auftritt?
Die 64-Bit Routinen beim AVR-GCC sind m.W. in C programmiert und als eine Art Basisimplementierung gedacht, die ohne Anpassung auf jeder Prozessorarchitektur verfügbar ist. Sie ist u.a. deswegen sehr langsam, weil in C nicht auf prozessorspezifische Dinge wie Carry-Flag u.ä. zuge- griffen werden kann, so dass Additionen (und damit auch Multiplikationen und Divisionen, die intern Additionen nutzen) nur sehr umständlich rea- lisiert werden können. Ich gehe aber davon aus, dass die IAR-Bibliothek bei den 64-Bit-Routinen direkt in Assembler implementiert und gut optimiert sind, so dass du mit Peters oder einer eigenen Implementation nicht unbedingt besser werden wirst. Wenn dir allerdings — wie im Thread-Titel angedeutet — 40 Bit reichen, könnte da schon etwas machbar sein. Bei den Addition sparst du damit etwa 37% Laufzeit, bei den Multiplikation noch mehr. Damit wäre eine Verbesserung von 6ms auf 4,4ms durchaus realistisch.
Icke_Wa schrieb: > Ich raffe noch nicht so ganz wie der Linker überhaupt weiß dass er > jetzt dein File nehmen soll und nicht die Standartvariante. Der GNU-Linker durchsucht die Libraries in einer bestimmten Reihenfolge, durch die die Prioritäten bei Mehrdeutigkeiten festgelegt werden. Es gibt auch Linker-Optionen, mit denen er angewiesen wird, bestimmte Symbole nicht aus der Standardbibliothek zu nehmen.
Klingt so als wäre das hier nicht sonderlich Erfolgsversprechend. Alternativ nen Tip wo ich mir die 40Bit Variante ins Hirn prügeln kann. Ne libary hab ich dazu bisjetzt nicht gefunden.
Das sollte doch kein Problem sein, die benötigten Operationen zu formulieren. Addition und Multiplikation sind direkt binomisch hinzuschreiben. Subtraktion über zwei Stufen und Division einfach interativ. Am Besten baust du dir das für einen 48Bit-Typ = 3*16. Das gibt Symmetrische Gleichungen und sollte nicht mehr Platz und Rechenzeit benötigen, als die 40er-Variante mit 16+16+8.
Hehe amen Bruder! Doch was dir so klar ist, ist mir gänzlich unklar. Den Code dafür erstmal zu formulieren macht mir garnicht sooo die Angst, aber ich habe einfach keine Ahnung wo ich das am besten mache. Wie ich dem Compiler dann klar mache dass es einen neuen Datentyp gibt und wo er hin muss um mit diesem Datentyp zu rechnen usw.
Aber direkt dazu vielleicht mal ne kurze Frage. Wenn ich das mache mit 3 Integers nehmen, dann sollte ich ja trotzdem die multiplikation in Assembler schreiben oder? In C kommen mir nur Ideen die dann wahrscheinlich genau so langsam wären. Wenn ich jetzt an ne Funktion ne oder besser 3 Integers übergebe. Wie muss ich die denn dann in Assembler ansprechen. Meine Register sind ja nur 8Bit lang, sprich. Wie finde ich herraus in welche beiden Register der mein INT packt?
http://www.nongnu.org/avr-libc/user-manual/group__asmdemo.html http://web.engr.oregonstate.edu/~traylor/ece473/lectures/assembly.pdf Aber, ganz echt, ich finde du solltest irgendwie deine Sprache überdenken. Möglicherweise bin ich inzwischen zu sehr gealtert aber um biegen und brechen flapsige Sprache benutzen zeugt in meinen Augen irgendwie nicht vom nötigen Ernst. Bitte um Verzeihung wenn das übertrieben ist.
Vielleicht würde auch schon ein zweites mal durchlesen reichen. Auf den Schlipps treten wollte ich hier zumindestens keinem. Meine Rechtschreibung und Satzstellung sind nur schon länger der Grund lieber was mit Zahlen zu machen ... Danke für die Links. Sobald ich wieder Zeit frei habe, werde ich mich da mal durchwühlen.
>Vielleicht würde auch schon ein zweites mal durchlesen reichen.
Bestimmt! Aber damit es nicht jeder 2-mal durchlesen muss, bitte ich
Dich, es selber 2 x durchzulesen und zu korrigieren, bevor Du auf den
"Absenden" Knopf klickst!
Ich stimme Clemens zu, Deine Texte sind wirklich sehr mühsam zu lesen
und zu verstehen.
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.