Modulo und Taktzyklen

Hi HJH,

ich mußte mir es auch erst 3x durchlesen bis ich kapiert habe was Step3 bedeuten soll, bis ich bemerkt habe das dies eine Modulo 128 Berrechnung ist. Deswegen führt folgende Zeile zum selben Ergebnis wie bei Dir:

$cs = $summe % 128; 

Bei Dir werde ich aus folgenden Zeilen nicht Schlau:


for($i=0; $i<strlen($Msg); $i++)     // alle Bytes aufsummieren  <---- $Msg als String
  $ChkSum += ord($Msg[$i]);        //                             <---- $Msg als Array
$ChkSum += strlen($Msg);             // zusätzlich die Anzahl der Bytes aufaddieren

Hallo Attain,

natürlich führt die Modulofunktion zum selben Ergebnis.
Bei meiner Version wird stattdessen eine simple UND-Verknüpfung verwendet. Der Unterschied zur Modulofunktion liegt in der Ausführungsgeschwindigkeit. Die Modulofunktion ist letztlich eine Division und diese wiederum ist verglichen mit einer Bit-Funktion eine „extrem“ aufwändige Angelegenheit. Bit-Funktionen können vom Prozessor in einem einzigen Takt abgearbeitet werden.

In den C-ähnlichen Programmiersprachen (C, C++, PHP, …) können Strings wie Arrays vom Datentyp Character behandelt werden. Davon mache ich hier Gebrauch.

Es geht sogar noch ein bischen kürzer, wenn man das Aufaddieren der Byte-Anzahl als Inkrement der Checksumme in die FOR-Schleife aufnimmt:

// die zu übertragende Byte-Sequenz steht in der String-Variablen $Msg
$ChkSum = 0;                                // Checksumme initialisieren
for($i=0; $i<strlen($Msg); $i++, $ChkSum++) // alle Bytes aufsummieren
  $ChkSum += ord($Msg[$i]);
$ChkSum &= 0x7f;                            // nur die unteren 7 Bit verwenden
$Msg .= chr($ChkSum). "\xF7";               // Byte-Sequenz um Checksumme und Endezeichen ergänzen 

Gruß
HJH

Hallo HJH

Ah… Die alte Schule… :smiley:

Ich vertrete allerdings mittlerweile den Standpunkt, dass solche Features, die den Programmierer zulasten des Prozessors entlasten durchaus ihre gerechtfertigte Position im Arbeitsablauf haben. Die Prozessoren werden immer schneller und die Zeit, die ein Dritter darüber grübelt was das wohin und zu welchem Zweck bitweise verschoben wird, wird immer teurer.

Wenn alle so arbeiten würden, auch wenn es noch so elegant ausschaut, währe die Hochsprache als solche vielleicht nie erfunden worden :wink:

Gruß,

Toni

Manchmal ist die alte Schule aber noch ganz gut, weil gelegentlich Mitmenschen/Kollegen der neuen Schule gar nicht mehr wissen, was ihre Anweisungen für eine Auswirkung haben könnten und sich wundern, was man mit einem optimierten Algorythmus alles rausholen kann. Da ist der Hinweis, was am Ende wirklich gemacht wird, durchaus erwähnenswert. Manche Compiler erkennen ja den „Sinn“ und optimieren die Codes selbstständig, aber bei PHP usw.wird ja nichts mehr optimiert, sondern nur noch interpretiert.
Als Hilfestellung sollte man allen Programmierern als Vorgabe "Z80, 16KB RAM " geben, damit mit den Resourcen nicht so „rumgeschweinert“ wird. Kein Wunder, das man heute für Sachen, die man früher mit dieser Ausstattung machen musste, schon einen Pentium4 und 1GB Ram braucht.

Tommi

Das erinnert mich an meine Zeit mit Assembler und einer 8Bit CPU von Motorola. Da haben wir jedes Byte dreimal umgedreht um mit den 64KByte RAM hinzukommen.

Grundsätzlich nicht verkehrt, dann würde es nurnoch Software geben die auch auf dem Z80 läuft aber der alles fehlt was den Speicher nur minimal belastet (grafische Ausgabe). Und du würdest nicht ernsthaft deine Haussteuerung auf nem Z80 machen wollen, oder? :wink:

Neenee. Es hilft nichts. Wer mit heute mit Programmierung sein Geld verdienen will kann, meiner Meinung nach, keinen optimierten, oder auch nur fehlerfreien, Code produzieren. Ist einfach zu teuer. Das wird auch solange so bleiben wie die Chefs von Programmieren Kaufleute sind. :mad:

TOni

Hi @ all,

ich finde den Hinweiß von HJH gar nicht so schlecht. Viele hier, so wie ich, sind sicher keine Profis im Programmieren. Und wenn man sich das recourcenschonende Programmieren gleich angewöhnt , ist das sicherlich nicht schlecht.Ich lerne gerne noch was dazu. Natürlich mußte ich die Aussage gleich mal überprüfen und hab mir mal was gebastelt.

$a = microtime();
for ($i=01; $i<=1000; $i++){
  $b = ($i) % 0x80;          // Modulo 128
  }
$c = microtime() -$a;

$a = microtime();
for ($i=01; $i<=1000; $i++){
  $b = ($i) & 0x7f;           // UND Verknpfung
  }
$d = microtime() -$a;

echo(($c/$d*100)-100 ."%");

Bei mir macht die Moduloberrechnung zwischen 5-10% mehr Zykluszeit aus obwohl das Ergebnis $b immer das selbe ist. Das ist schon einiges.

MfG
Attain

Hallo Attain,

Dein Testroutine liefert zwar ein brauchbares Ergebnis, enthält aber einen Fehler:

Die Funktion microtime() liefert ohne Parameter einen zweiteiligen String, keine Zahl! Der erste Teil enthält die Sekundenbruchteile und der zweite Teil den Unix Timestamp. Es ist der Geschicklichkeit von PHP zu verdanken, dass es bei den Berechnungen offenbar nur den ersten Teil verwendet. Wenn die Differenz größer als 1 Sekunde ist, dann funktioniert es so nicht mehr.

Du solltest microtime(true) verwenden, also mit dem Parameter true, dann liefert die Funktion einen echten Float-Wert.

Ich habe die Schleifenzahl auf 1 Mio. erhöht und komme so reproduzierbar auf Werte zwischen 15% und 20% (3GHz CPU). Bei weniger Durchläufen (1k oder 10k) sind die Schwankungen sehr groß.

Danke für dieses Testskript. :slight_smile:

Gruß
HJH

okay… ich musste nach deiner Formel auch etwa 20% bessere Leistung für die Bitoperation feststellen.

Aber zu meiner Verteidigung: Ein messbarer Unterschied ist erst ab 100.000.000 Zyklen zu verzeichnen weil ich nicht kleiner als millisekunden auswerten kann. Der Geschwindigkeitsvorteil dürfte pro Aktion bei einem Bruchteil einer Nanosekunde liegen.

Rechnerisch also bei einem Prozessor@2GHz alle 0,0000005 Millisekunden 0,000000125 Millisekunden einsparen (theoretisch - versteht sich). Gemessen mit einer „echten“ Programmiersprache (Delphi) - also binärcode, nicht PHP. PHP ist von natur aus langsamer.

Gruß,

Toni

Hallo Toni,

überleg doch mal:
1GHz entspricht einer Taktperiode von 1ns. Wenn der Geschwindigkeitsvorteil, wie Du sagst, im Sub-Nanosekundenbereich liegen sollte, dann wäre der Unterschied zwischen beiden Verfahren nur etwa 1 Taktperiode. Man sieht sehr schnell, dass Deine Schlussfolgerung nicht stimmen kann. In einer Taktperiode kann auch der schnellste Prozessor keine Division durchführen.

Das hat folgenden Grund:
Die hier verwendeten Schleifen sind so winzig, dass sie problemlos in den CPU-Cache passen. Dort kann der Prozessor seine volle Geschwindigkeit ausspielen. Hinzu kommt, dass PHP zwar eine langsame Skriptsprache ist, aber die zur Berechnung verwendeten Mathematikroutinen als compilierte Bibliotheken vorliegen. Diese sind, wenn sie erst einmal geladen sind genau so schnell wie die einer echten Programmiersparache.

Normalerweise werden Berechnungen, wie wir sie hier zur Demonstration einsetzen, nicht in ewig langen Schleifen abgearbeitet, sondern meist nur einmal. Der CPU-Cache verfälscht hier das Ergebnis gewaltig.

Wenn wir die Möglichkeit hätten die tatsächliche Abarbeitungszeit einer einzelnen un-gecachten PHP-Anweisung zu messen, würden wir eher einen Unterschied in der Größenordnung 100…1000 (!) feststellen, also z.B. 10ns für die Bit-Operation und 1…10µs für die Division.

Die Cache-Strategien moderner CPUs sind eine echte Wissenschaft. Man muss zugeben, dass die Hersteller hier wirklich großartige Leistungen vollbracht haben. Von einem solchen Cache kann ein Z80 natürlich nicht einmal träumen.

Gruß
HJH

PS: Es ist schade, dass fast jeder Thread hier im Forum in ein anderes Thema abdriftet. Aber daran bin ich ja selbst nicht ganz unschuldig. :wink:

Jap, Ich bin oben bei 2 GHz ebenfalls auf 0,5ns gekommen und hab einfach die (aufgerundeten) Prozente, die ich ermittelt hab darauf angewendet. Ganz banal also ohne tiefgründigen Gedankenansatz.

Natürlich hast du recht, dass das so direkt nicht geht. Aber die 25%, die ich ersatzweise angenommen hab, kommen ja tatsächlich, wie auch immer geartet, zustande. Ob ich nun alle 0,5ns eine achtel, jede volle eine viertel oder alle 4 ns eine ganze dazugewinne ist dann doch nur noch Statistik. Dass die Deutschen im Schnitt 1,8 Kinder haben ist auch nicht Praxisnah aber niemand würde ohne ein schmunzeln behaupten, dass 20 deutsche 18 Kinder bekommen, oder? Die armen Mütter… :wink:

Dein kritikpunkt, dass dieser Test wenig Praxisnah ist, kann ich nur unterstützen. Nicht nur weil er meine einleitende Aussage, dass es heute unnötig geworden ist seinen Code derart zu optimieren, unterstützt. :smiley: Er zeigt aber, denke ich, die Dimensionen auf in denen wir uns bewegen. Die sind verschwindend gering. Ich behaupte sogar selbst wenns 300% wären wärs noch egal.

Ist ja kein Beinbruch. Nichts was man nicht korrigieren könnte… Habs mal getrennt.

Toni