Hallo Ich habe eine Frage was eine vereinfachung des Codes heissen könnte. Ich muss in meinem Programm 100000000/eine zahl rechnen. Dies funktioniert auch bestens. Jedoch wie ich weiss werden so viele rechenschritte benötigt um dies in meinem C code abzuarbeiten. Gibt es eine vereinfachte form wie schieben oder so. So währe dies ein wenig freundlicher vom code her. Danke im voraus.
:
Bearbeitet durch User
Simon X. schrieb: > Gibt es > eine vereinfachte form wie schieben oder so Optimierung einschalten, den Rest erledigt der Optimizer
Den darf ich nicht einschalten, da es im Programm eine Stelle hat die genau so durchgeführt werden muss wie sie steht. Aber was gäbe es für eine schönere Schreibweise?
Simon X. schrieb: > Jedoch wie ich weiss werden so viele > rechenschritte benötigt um dies in meinem C code abzuarbeiten. Die entscheidende Frage ist aber nicht, ob es viele sind, sondern ob es zuviel sind. Für Ausgaben an den langsamen Menschen langweilt sich eine CPU dabei nur.
Simon X. schrieb: > Den darf ich nicht einschalten, da es im Programm eine Stelle hat > die > genau so durchgeführt werden muss wie sie steht. Aber was gäbe es für > eine schönere Schreibweise? Dein Programm ist falsch.
Simon X. schrieb: > Den darf ich nicht einschalten, da es im Programm eine Stelle hat die > genau so durchgeführt werden muss wie sie steht Dann korrigiere diese Stelle entsprechend, das ist in 99% der Fälle möglich. Welche Architektur ist es? Ist der Divisor fix oder zur Laufzeit variabel?
:
Bearbeitet durch User
Auf was für einem Prozessor programmierst du? Manche ALUs können bestimmte Rechenoperationen optimiert ausführen (bei manchen DSPs z.B. sogar in einem Prozessortakt). Wenn du das gecheckt hast, schau mal nach Bitshiften...ein Einstieg gibts hier https://stackoverflow.com/questions/2776211/how-can-i-multiply-and-divide-using-only-bit-shifting-and-adding
:
Bearbeitet durch User
Simon X. schrieb: > Den darf ich nicht einschalten, da es im Programm eine Stelle hat die > genau so durchgeführt werden muss wie sie steht. Welchen Compiler nutzt Du denn? Kannst Du über Präprozessorangaben die Optimierung für den Teil abschalten?
Simon X. schrieb: > Den darf ich nicht einschalten, da es im Programm eine Stelle hat die > genau so durchgeführt werden muss wie sie steht. "broken by design"
Nutze einen ATmega2560 bei 16MHz. mit dem ICE Atmel compiler. Der divisor ist so im Datenblatt vorgegeben. So versuche ich das Programm nur zu optimieren. Mit dem compiler möchte ich eigentlich nicht arbeiten. Ist für mich nur eine halbe Lösung zu dem Problem und nicht das Problem aus der Welt geschaffen.
Harry L. schrieb: > Simon X. schrieb: >> Den darf ich nicht einschalten, da es im Programm eine Stelle hat die >> genau so durchgeführt werden muss wie sie steht. > > "broken by design" Die Arbeit dem Compiler zu überlassen heisst für mich das man Faul ist und nicht. Aber verstehen ist was anderes. Es gibt tatsächlich stellen oder Rechenschritte die genau so erledigt werden müssen und nicht umgangen werden können.
Simon X. schrieb: > mit dem ICE Atmel compiler. Das ist ein Debugger. Simon X. schrieb: > Der > divisor ist so im Datenblatt vorgegeben. Wenn Divisor (aus dem Datenblatt) und Dividend (100000000) fix sind, wird die Berechnung sowieso immer zu einer fixen Zahl vorberechnet. Simon X. schrieb: > Mit dem compiler möchte ich eigentlich nicht > arbeiten. Ohne Compiler kannst du auf dem AVR wohl kaum C nutzen. Was meinst du wirklich? Simon X. schrieb: > Ist für mich nur eine halbe Lösung zu dem Problem und nicht > das Problem aus der Welt geschaffen. Meinst du den Optimierer? Den darf man ruhig ordentlich ausnutzen, dafür ist der da. Ohne Optimierung zur kompilieren ist angezogene Handbremse. Simon X. schrieb: > Die Arbeit dem Compiler zu überlassen heisst für mich das man Faul ist > und nicht. Das heißt dass man kompakten, lesbaren und wartbaren Code schreibt und die Details dem Computer überlässt. Das ist ökonomisch. Wenn man unbedingt alles selber machen will, macht man es in Assembler. Übrigens beschleunigt der Optimizer selbst die besten C-Programme noch; ohne Optimierung baut der Compiler immer unnötige Dinge ein. Simon X. schrieb: > Es gibt tatsächlich stellen > oder Rechenschritte die genau so erledigt werden müssen und nicht > umgangen werden können. Wenn sie korrekt formuliert sind, wird da auch nichts umgangen und das genau so gemacht wie gewünscht. Präzisiere das mal, was "genau so" erledigt werden soll und was der Optimierer da kaputt machen könnte.
:
Bearbeitet durch User
“The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.” Donald Knuth
Simon X. schrieb: > Den darf ich nicht einschalten, da es im Programm eine Stelle hat die > genau so durchgeführt werden muss wie sie steht. Kannst du uns bitte ein Beispiel geben, wo bei dir der Optimizer nicht aktiv werden darf? Ansonsten kann man sehr bequem für Teile des Programms die Optimierung verbieten oder umschalten. #pragma GCC push_options #pragma GCC optimize ("O0") hier dein kritischer Code #pragma GCC pop_options
Georg G. schrieb: > #pragma GCC push_options > #pragma GCC optimize ("O0") > > hier dein kritischer Code > > #pragma GCC pop_options wenn man das braucht, hat man mit sehr großer Wahrscheinlichkeit ein fehlerhaftes Programm.
Dummschwaetzer schrieb: > oder der Compiler hat bugs Die finden in der Regel nur Programmieranfänger. Ausnahmen hiervon sind extrem selten. Woran mag das liegen?
Simon X. schrieb: > Jedoch wie ich weiss werden so viele > rechenschritte benötigt um dies in meinem C code abzuarbeiten. Wenn die 'eine Zahl' (der Divisor) eine Variable ist, dann weißt du es nicht. Je nach dem welchen Wert die hat, werden daraus mehr oder weniger Operationen. > Gibt es > eine vereinfachte form wie schieben oder so. So währe dies ein wenig > freundlicher vom code her. Schieben geht einfach, wenn der Divisor eine Zweierpotenz ist. Simon X. schrieb: > Die Arbeit dem Compiler zu überlassen heisst für mich das man Faul ist > und nicht. Und nicht was? Aber grundsätzlich: die Optimierung eines Programms kann der Compiler mit seinem Optimizer am besten. Das hat nichts mit Faulheit zu tun.
Simon X. schrieb: > Den darf ich nicht einschalten, da es im Programm eine Stelle hat die > genau so durchgeführt werden muss wie sie steht. Interessant: Du haellst dich fuer besser und kompetenter als die Compilerbauer? Hut ab... Simon X. schrieb: > Es gibt tatsächlich stellen > oder Rechenschritte die genau so erledigt werden müssen und nicht > umgangen werden können. Und du glaubst, das dein Programm das einzige auf dieser Welt ist, wo das der Fall ist, bzw. das alle anderen Entwickler auf der Welt fuer sowas die optimierung abschalten? Auch hier: Hut ab... Simon X. schrieb: > So versuche ich das Programm nur zu optimieren. Genau hier faengt dein eigentliches Problem an: Du haellst dich fuer besser und kompetenter als die Compilerbauer. Okay: Der Optimierer kann auch nicht zaubern, z.B. wenn der Code sehr schlecht ist. Zeig doch bitte mal ein Stueckchen Code (compilierbar!) das dein Problem (also was die optimierung angeblich kaputt macht) fuer alle anderen hier im Forum nachvollziehbar zeigt.
Und wer glaubt, dass der Compiler keine Optimierungen durchführt, wenn du mit -O0 compilierst?
Simon X. schrieb: > Mit dem compiler möchte ich eigentlich nicht > arbeiten. Ist für mich nur eine halbe Lösung zu dem Problem und nicht > das Problem aus der Welt geschaffen. Was, bitte, soll das nu heißen?? Du hast also einen C-Code, den du an einer Stelle optimieren möchtest - was das auch immer bedeuten soll und dann? Gruß Rainer
Harry L. schrieb: > Simon X. schrieb: >> Den darf ich nicht einschalten, da es im Programm eine Stelle hat die >> genau so durchgeführt werden muss wie sie steht. > > "broken by design" Jau, aber anders als du denkst. Auch wenn es C nicht in den Kram passt, sind nunmal u.U. bestimmte Codeteile mit bestimmten Timing-Constraints zu bearbeiten, um das gewünschte Ergebnis zuverlässig zu erreichen. "broken by design" ist also hier: Verwendung einer ungeeigneten Sprache, nämlich einer die nur unvollkommene bis gar keine Kontrolle über die verbrauchte Rechenzeit ermöglicht. Dass das meist nicht völlig dramatisch im Sinne einer kompletten Unbenutzbarkeit ist, liegt einfach nur daran, dass in sehr vielen Fällen "schnell genug" ausreichend ist. Das Problem ist aber auch hier: Man sollte eigentlich zumindest eine obere Grenze angeben können, bis zu der die Timing-Constraints eingehalten werden können... Völlig unbrauchbar ist C allerdings prinzipiell für alles, wo es nicht genügt, schnell genug zu sein, sondern eine (ggf. innerhalb bestimmter Grenzen) exakte Laufzeit erforderlich ist.
c-hater schrieb: > Völlig unbrauchbar ist C allerdings prinzipiell für alles, wo es nicht > genügt, schnell genug zu sein, sondern eine (ggf. innerhalb bestimmter > Grenzen) exakte Laufzeit erforderlich ist. Es ist allerdings recht unwahrscheinlich dass der TE genau solch einen Fall vorliegen hat.
Simon X. schrieb: > Ich muss in meinem Programm 100000000/eine zahl rechnen. Dies > funktioniert auch bestens. Jedoch wie ich weiss werden so viele > rechenschritte benötigt um dies in meinem C code abzuarbeiten. Gibt es > eine vereinfachte form wie schieben oder so. So währe dies ein wenig > freundlicher vom code her. Ohne irgendetwas über den Kontext und "eine zahl" zu wissen, wird das schwierig. Wenn es i.A. einfacher ginge, wäre die Division in der Praxis überflüssig. Du musst schon etwas mehr Information über dein eigentliches Problem rausrücken. Falls "eine zahl" bspw. immer 0x00BEBC20 ist, würde sich die Operation fast in Luft auflösen.
Es wurde immer noch nicht die Frage beantwortet, ob das Programm überhaupt zu langsam ist. Solange das nicht feststeht, ist eine Optimierung überflüssig wie ein Kropf.
Simon X. schrieb: > Ich muss in meinem Programm 100000000/eine zahl rechnen. Dies > funktioniert auch bestens. Jedoch wie ich weiss werden so viele > rechenschritte benötigt um dies in meinem C code abzuarbeiten. Gibt es > eine vereinfachte form wie schieben oder so. So währe dies ein wenig > freundlicher vom code her. Es gibt für die Version "Variable"/" Konstante" die Umformung in "Variable"*"andere Konstante">>"noch eine andere Konstante". Das ganze nennt sich Barrett-Verfahren und wird vom GCC in der Tat vollautomatisch eingesetzt, sobald Optimierungen aktiv sind und es der Wertebereich erlaubt. Für deine Problematik, d.h. "Konstante"/"Variable" existiert meines Wissens nach kein derartiges verfahren.
Peter D. schrieb: > Solange das nicht feststeht, ist eine Optimierung überflüssig wie ein > Kropf. Unabhängig davon ist es aber auch recht sinnlos, den Compiler so einzustellen, dass er besonders ineffizienten Code produziert, um sich dann den Kopf darüber zu zerbrechen, wie man das von Hand wieder gerade biegen könnte. Und dass … Simon X. schrieb: > es im Programm eine Stelle hat die genau so durchgeführt werden muss wie > sie steht … glaube ich nicht. So eine Aussage kommt eigentlich immer durch das fehlende Wissen, wie man es richtig macht.
Simon X. schrieb: > da es im Programm eine Stelle hat die > genau so durchgeführt werden muss wie sie steht. Also der Optimizer/Compiler wird meines Wissens nicht etwas konstruieren, was andere Ergebnisse liefert als von dir per Code angestrebt. Mich dünkelt, dass du über sehr wenig Kenntnisse darüber verfügst und du dir selber im Wege stehst.
Ingo L. schrieb: > Also der Optimizer/Compiler wird meines Wissens nicht etwas > konstruieren, was andere Ergebnisse liefert als von dir per Code > angestrebt. Dazu muss der Code aber korrekt sein. Es gibt in C und C++ leider viele Möglichkeiten, (unbemerkt) fehlerhaften Code zu produzieren, welcher dann ggf. kaputt optimiert wird. Insbesondere bei Zugriffen auf Hardware-Register, bei denen Reihenfolge und Timing wichtig sind, bewegt man sich in einer Grauzone. Da aber IIRC die AVR hier relativ gutmütig sind sollten sich Lösungen finden lassen. Es wäre praktisch, die fragliche Codestelle mal sehen zu können...
Simon X. schrieb: > Es gibt tatsächlich stellen oder Rechenschritte die genau so erledigt > werden müssen und nicht umgangen werden können. Dann muss man die "Stellen" einfach so programmieren, dass sie immer das machen, was sie tun sollen. Mit Optimierung halt schneller... Wenn ich Code habe, der ohne Optimierung läuft und mit Optimierung nicht mehr, dann weiß ich, dass der Code noch einen Fehler enthält.
Ich glaube ich habe es verstanden. Der Fragesteller möchten bespasst werden. Irgendwas soll passieren, damit irgendwas anders wird. Kein Problem, dann machen wir das. De actio juméntis insipiéntibus schlage ich eine Zerlegung in einen Kettenbruch vor. Das ist ein bisschen altmodisch (schon Euler hat ...) aber kann man mal machen. Die Mathematik ist ein bisschen aufwendiger, aber es gibt ein klassisches Lehrbuch online: https://archive.org/download/dielehrevondenk00perrgoog/dielehrevondenk00perrgoog.pdf
Ob mit oder ohne Compileroptimierung, die Division dauert immer gleich lang. Es wird immer die gleiche Lib aufgerufen. Man kann zur Optimierung aber auch float statt long nehmen. Float berechnet nur 24 Bit und ist daher schneller.
Hannes J. schrieb: > Ich glaube ich habe es verstanden. Der Fragesteller möchten bespasst > werden. Irgendwas soll passieren, damit irgendwas anders wird. Kein > Problem, dann machen wir das. Da warst Du jetzt schneller ;-) Es geht um freundlichen Code! Vielleicht einen, der Beträge von der einen in eine andere Währung umrechnet. Vielleicht gibt es auch noch eine Optimierung, die dafür sorgt, daß der µC nicht ca. 10000000 Befehle/s vergeudet. Als Nächstes wird sicherlich stören, daß der Flash-Speicher nicht auf das letzte Byte gefüllt ist. Preisenkung vom Lieferanten? Interessant, welche Probleme heutzutage in der Schule gelöst werden müssen.
Hannes J. schrieb: > schlage ich eine Zerlegung in einen Kettenbruch Ich werfe mal Subtraktion und Addition in einer Schleife ins Forum. Division ist wiederholte Subtraktion, also kann man das auch so hinschreiben.
S. R. schrieb: > Division ist wiederholte Subtraktion, also kann man das auch so > hinschreiben. Angenommen, die fragliche Zahl wäre die 341256. Jetzt schreib mal die Aufgabe 100000000/341256(*) als Subtraktionen hin. Ich wüßte nicht, wie ich das anstellen soll. Aber wenn du das so einfach findest, schreib mal bitte auf, wie du das machen würdest. (*) Die wirkliche Zahl wissen wir alle nicht, deshalb nur als Beispiel
Hannes J. schrieb: > Ich glaube ich habe es verstanden. Der Fragesteller möchten bespasst > werden. Das glaube ich mittlerweile auch! Und wenn man nicht weiss, wie groß die zweite Zahl sein wird, dann bleibt doch nur eine Float-Division. Auch wenn ich - wie gesagt- keine große Ahnung in "C" habe, so scheint es mir doch völlig unsinnig, in einer Hochsprache eine Rechenoperation "zu Fuss" selbst zu schreiben... Und noch einmal meine Frage: der TO hat ein C-Programm, möchte aber keinen Compiler benutzen! Also was denn dann!!! Gruß Rainer
Fritz B. schrieb: > Angenommen, die fragliche Zahl wäre die 341256. Jetzt schreib mal die > Aufgabe 100000000/341256(*) als Subtraktionen hin. Ich wüßte nicht, wie > ich das anstellen soll. Aber wenn du das so einfach findest, schreib mal > bitte auf, wie du das machen würdest.
1 | int divisor = 100000000, quotient = 341256, result = 0; |
2 | divisor -= quotient / 2; |
3 | while(divisor > 0) |
4 | {
|
5 | divisor-=quotient; |
6 | result++; |
7 | }
|
Nachtrag: Ja, natürlich ist das Unfug, den Code selber zu schreiben, weil der Compiler das ziemlich sicher auch genau so in Assembler umsetzen wird.
Fritz B. schrieb: > S. R. schrieb: >> Division ist wiederholte Subtraktion, also kann man das auch so >> hinschreiben. > > Angenommen, die fragliche Zahl wäre die 341256. Jetzt schreib mal die > Aufgabe 100000000/341256(*) als Subtraktionen hin. Ich wüßte nicht, wie > ich das anstellen soll. Aber wenn du das so einfach findest, schreib mal > bitte auf, wie du das machen würdest. Hast du im Fach Informatik in der Uni gepennt? Das was jz23 da aufgeschrieben hat, ist eines der ersten Dinge die man lernt wwenn es darum geht ein wenig davon zu verstehen was unter der haube von Programmiersprachen geschieht :)
Fritz B. schrieb: > Angenommen, die fragliche Zahl wäre die 341256. Jetzt schreib mal die > Aufgabe 100000000/341256(*) als Subtraktionen hin. Ich wüßte nicht, wie > ich das anstellen soll. Dann hast du in der Schule wahrscheinlich die Unterrichtseinheit über schriftliche Division verpasst. Den ersten Kontakt mit der Vorgehensweise hättest du normalerweise im zweiten Halbjahr der 4ten Klasse haben sollen.
Alex G. schrieb: > Das was jz23 da aufgeschrieben hat, ist eines der ersten Dinge die man > lernt wwenn es darum geht ein wenig davon zu verstehen was unter der > haube von Programmiersprachen geschieht :) Und das weiß sogar ich, der nie Informatik studiert hat. :-)
Niklas G. schrieb: > Es gibt in C und C++ leider viele > Möglichkeiten, (unbemerkt) fehlerhaften Code zu produzieren, welcher > dann ggf. kaputt optimiert wird. Wie kann denn kaputter Code noch kaputt optimiert werden? Der Code war schon vor der Optimierung kaputt, der Compiler und seine Optimierung machen den Fehler nur sichtbar. Sowas wie "ein bisschen schwanger" gibt es nicht. Entweder man ist es oder nicht. Und das ist auch etwas was jedem klar sein muss wenn man mit C/C++ arbeitet: Wenn man den Compiler mit Mist fuettert kann man nicht erwarten das Rosen dabei raus kommen.
Kaj schrieb: > Der Code war schon vor der Optimierung kaputt, der Compiler und seine > Optimierung machen den Fehler nur sichtbar. Ja. Es war umgangssprachlich unpräzise formuliert.
Kaj schrieb: > Wenn man den Compiler mit Mist fuettert kann man nicht erwarten das > Rosen dabei raus kommen. Oder kurz: Shit in - shit out.
Leute, das ist nicht mehr wirklich witzig. Ihr tut so als ob der TE aus Dummheit dieses Problem hätte und als ob ihr alle immer perfekten code schreiben würdet (und das vorallem schon seit eurer ersten Bekanntschaft mit einer Tastatur) >_> Wart ihr nie in der Situation einmal sehr froh gewesen zu sein dass der code überhaupt lief. Egal wie? Optimierungen auszuschalten ist da noch bei weitem das angenehmste. Wenn ihr den TE nicht vollends verschreckt habt, beschreibt er aber vieleicht die betreffende code Stelle und man kann wieder was sinnvolles in diesen Thread schreiben.
:
Bearbeitet durch User
Peter D. schrieb: > Es wurde immer noch nicht die Frage beantwortet, ob das Programm > überhaupt zu langsam ist. Und die 2. Frage ist, falls es zu langsam ist, ob dann überhaupt die Division der schuldige ist. Ich hab da schon Sachen erlebt. Z.B. daß jemand für eine Multiplexanzeige jedesmal neu die Zahl komplett in Ziffern zerlegt, um dann davon ein Digit auszugeben. Wer Rechnungen unnötig oft ausführt, darf sich nicht wundern, wenn dann wichtige Sachen zu langsam werden.
Alex G. schrieb: > Optimierungen auszuschalten ist da noch bei weitem das angenehmste. Aber böse geschummelt. Es ist schon sinnvoll direkt zu lernen wie es richtig geht. Sonst gibt's bald ein böses Erwachen... Dazu kann man ja auch fragen wo genau das Problem liegt, wenn man es eingegrenzt hat. Alex G. schrieb: > Wenn ihr den TE nicht vollends verschreckt habt, beschreibt er aber > vieleicht die betreffende code Stelle und man kann wieder was sinnvolles > in diesen Thread schreiben. Macht er ja leider nicht :-/
Alex G. schrieb: > Hast du im Fach Informatik in der Uni gepennt? Ich war weder an der Uni noch hab ich das Fach Informatik gehabt. Es ist bemerkenswert, wie du darauf kommst, daß alle, die hier schreiben, an der Uni gewesen wären. Aber trotzdem danke für die herablassende Beleidigung ;-) @jz23: Ich danke dir. Mit etwas nachdenken hätte ich selbst drauf kommen müssen...
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.