@Horst_h: Nein, ich werde die Testbedingungen jetzt
NICHT ändern, während täglich neue Ergebnisse hereinkommen! Punkt!
mschnell hat geschrieben:Falls es Dir um die Optimierung z.B. der Funktion "Suche Character in String" geht, noch ein Vorschlag.
Es könnte sein, dass alle oder auch nur manche Chips bei langen Strings schneller arbeiten, wenn nicht jedes Byte einzeln aus dem Speicher geholt wird, sonder die Wortbreite beim Speicherzugriff explizit durch den Assembler-Code ausgenutzt wird.
Es könnte also z.B. bei 32 Bit die Schleife über 4-Byte-Gruppen laufen und dann die 4 Bytes in einem 32 Bit Register gecheckt werden.
(Bei 64 Bit Mode entsprechend.)
Michael, Du hast recht! Aber das ist keineswegs trivial.
Schau Dir doch bitte mal die Unit
SortableHashList.pas genauer an (die ist in den Sourcen von AlignTest). Dort gibt es zwei Funktionen "
ShortCompareSensitive" und "
ShortCompareInsensitive" jeweils in Assembler-Fassungen für x86_64 und i386 sowie als Pascal-Variante für nicht-x86er-Prozessoren (übrigens handelt es sich um zwei unterschiedliche Algorithmen, die x86_64-Funktionen sind eine Entwicklungsgeneration weiter und nochmal ein paar Prozent schneller - ich hatte einfach noch nicht die Zeit gefunden, die 32-Bit-Versionen entsprechend anzupassen und zu testen). Dort geschieht genau das, was Du vorschlägst: Einlesen in Long- bzw. Quadbreite in die Register. Es ist nicht ganz trivial, denn man muß ja auch kontrollieren,
wie oft man entsprechende Register-Shifts und Vergleiche unternimmt. Also wird der Quelltext entweder quälend lang (Abfolge mit vielen Wiederholungen statt Schleife pro Registerblock) oder man codiert entsprechende Schleifen, die schnell mehr Zeit verbrauchen, als das Ganze einbringt. Da das richtige Maß zu finden ist nicht ganz leicht.
Damit bei einer
CharPos-Funktion noch etwas zu gewinnen, wird allerdings sehr schwer werden. Denn die ist schon von sich aus so eng, daß das gesamte Einsparpotential pro Char (bei 32-Bit) gerade mal
(3 * mov(mem,reg) - 1 * shr($16,reg)) / 4 beträgt. Das ist schnell wieder verbraten, wenn es den Algorithmus verkompliziert! Ich bin in diesem Zusammenhang übrigens noch auf ein anderes Problem gestoßen, bei dem ich nicht weitergekommen bin: Gerade hier wäre es nämlich sehr viel einfacher,
immer blockweise einzulesen,
ohne zu kontrollieren, ob man damit schon über das Ende des Strings hinausliest. Ich habe mir das nicht getraut, weil ich mir nicht sicher bin, ob man damit nicht (in sehr seltenen Fällen) eine Memory-Zugriffsverletzung riskiert. Vielleicht weiß jemand darauf eine Antwort?
Hier bei
AlignTest ging es mir
gerade nicht darum, ein
allgemeinverbindliches Optimum zu finden. Das hatte ich mit den Pos(String, String)-Funktionen monatelang versucht und es ist mir immer mehr entglitten, was überhaupt
allgemeingültig sein könnte. An der Stelle habe ich dann einen Schnitt gemacht, bewußt die denkbar minimalistischste Funktion genommen und diese variiert. Und jetzt ist die spannende Frage: Kann man auf niedrigster (Assembler-) Ebene überhaupt Codefolgen finden, die auf (nahezu) allen Rechnern gut bis perfekt laufen, oder sieht man da kein Land und
muß sich damit abfinden, daß alles, was auch immer man macht, auf dem einen Rechner eben super läuft und auf dem nächsten ggfls. quälend langsam (ich rede von der Micro-Code-Ebene, nicht von Algorithmen-Optimierung). Mit welcher Unschärfe müssen wir leben? Auf diese Frage versuche ich, eine Antwort zu finden. Nein, besser gesagt: Einer Antwort
näherzukommen.
Die CharPos-Funktionen, die im Test verwendet werden, sind mit einiger Wahrscheinlichkeit noch
nicht das Ende der Fahnenstange. Aber diese Frage habe ich im Moment zurückgestellt. Stattdessen möchte ich derzeit erstmal wissen:
Gibt es denn soetwas wie ein verbindliches "Ende der Fahnenstange" überhaupt? Oder rennt man da einer Fata Morgana hinterher?
Gruß Rüdiger