Autor Beitrag
Allesquarks
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Do 24.07.08 16:25 
Kurze Boolsche Auswertung heißt bsp:
ausblenden Delphi-Quelltext
1:
if (a=3and (b=4and (c=5)					
, dass er schon aufhört wenn a<>3 ist, da das Ding dann insgesamt nicht mehr true werden kann.
Bei dir werden über die = mehrere logische Werte angelegt. Intern sind das immer noch bytes (kleinste Speichereinheit), aber das interessiert dabei eher weniger.

Außerdem würde ich noch das try except enfernen. Da doch eigentlich immer ein gültiger Schlüssel übergeben wird sollte auch kein Stuss rauskommen den man abfangen sollte.
Diesen Generaltext, den du hardgecoded da drin hast würde ich wenn möglich auch initial am besten als constant anlegen und dann als Zeiger übergeben.
Mach mal einen Breakpoint bei der max function und mach das CPU-Window auf und guck ob da irgendwas von call steht. Wenn ja dann sag Bescheid.
Generell würde ich dem Delphi-Compiler so wenig wie möglich selbst überlassen.
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Do 24.07.08 16:37 
user profile iconAllesquarks hat folgendes geschrieben:
Kurze Boolsche Auswertung heißt bsp:
ausblenden Delphi-Quelltext
1:
if (a=3and (b=4and (c=5)					
, dass er schon aufhört wenn a<>3 ist, da das Ding dann insgesamt nicht mehr true werden kann.
Bei dir werden über die = mehrere logische Werte angelegt. Intern sind das immer noch bytes (kleinste Speichereinheit), aber das interessiert dabei eher weniger.


Ach so meintest du. Okee, werde ich machen.



user profile iconAllesquarks hat folgendes geschrieben:

Diesen Generaltext, den du hardgecoded da drin hast würde ich wenn möglich auch initial am besten als constant anlegen und dann als Zeiger übergeben.

Diesen Text habe ich in einer Duplikatversion mal direkt in die Datenbank ein bisschen weiter reinverpflanzt, und so war es schon mal schneller als ursprünglich. Aber werde auch noch den Vergleich mit dem Zeiger anstellen, danke für den Hinweis.



user profile iconAllesquarks hat folgendes geschrieben:

Mach mal einen Breakpoint bei der max function und mach das CPU-Window auf und guck ob da irgendwas von call steht. Wenn ja dann sag Bescheid.


Jep, er ruft den Max an. Was bedeutet jetzt das? Ist das Positiv oder Negativ?

Zitat:
move edx [ebp-$08]
move eax,ebx
call max
Allesquarks
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Do 24.07.08 17:09 
Probier mal das vor allem mit inline und guck mal erneut nach dem call. Falls er es nicht inlined ists vlt ja auch so schneller, obwohl die max aus math sehr ähnlich sein dürfte. Vor allem könnte es auch einen Unterschied machen wierum du die beiden Zahlen übergibts => ausprobieren.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function _max(Zahl1,Zahl2:integer):integer;inline;
asm
    cmp eax,edx;
    jb @@switch;
    ret;
  @@switch:
    xchg eax,edx;
end;

Edit: VLT lässt sich diese Version besser inlinen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function _max(Zahl1,Zahl2:integer):integer;inline;
asm
    cmp eax,edx;
    jge @@done;
    xchg eax,edx;
    @@done:
end;
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Do 24.07.08 17:17 
user profile iconAllesquarks hat folgendes geschrieben:
Probier mal das vor allem mit inline und guck mal erneut nach dem call. Falls er es nicht inlined ists vlt ja auch so schneller, obwohl die max aus math sehr ähnlich sein dürfte. Vor allem könnte es auch einen Unterschied machen wierum du die beiden Zahlen übergibts => ausprobieren.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
function _max(Zahl1,Zahl2:integer):integer;inline;
asm
    cmp eax,edx;
    jb @@switch;
    ret;
  @@switch:
    xchg eax,edx;
end;


Declaration expected but 'INLINE' found.


Noch was anderes. Ich bin nicht sicher, ob du den Sinn von "max" im Programmcode verstanden hast. Die Funktion max() wird für das Programm überhaupt NICHT benötigt. Doch während meinen Leistungstests hat sich gezeigt, dass das ganze Programm einiges schneller ist, wenn diese Funktion darin vorhanden ist (auch wenn sie keinen Einfluss aufs Programm hat). Von da her müsstest du nicht versuchen, sie zu optimieren. ;) Falls du auf der Suche bist, warum es bei mir dadurch schneller ist, dann hab ich nix gesagt ;)
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 24.07.08 20:01 
ein ASM code lässt sich nicht inlinen, das ist eine der einschränkungen.

PS: Walter, mein tipp ist immer noch, schau doch erst mal, dass das programm rund läuft, bevor du dich auf die performance optimierung einlässt.
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Do 24.07.08 20:41 
user profile iconGrenzgaenger hat folgendes geschrieben:
PS: Walter, mein tipp ist immer noch, schau doch erst mal, dass das programm rund läuft, bevor du dich auf die performance optimierung einlässt.



Das Programm läuft schon lange. Wäre eigentlich fertig. Alles was noch fehlt ist die Performance. Und die Probleme, wegen welchen ich hier immer mal wieder nach Hilfe schreie, tauchen meistens bei irgend einer Optimierung oder sonst etwas auf.


Edit: Ich habe gefunden, welche Prozedur mir praktisch die ganze Zeit frisst (in etwa 23 Sekunden der benötigten 24):

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
procedure TCipher_1DES.DoInitKey(const Data: array of Byte; Key: PLongArray; Reverse: Boolean);
const
  ROT: array[0..15of Byte = (1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28);
var
  I,J,L,M,N: LongWord;
  PC_M,PC_R: array[0..55of Byte;
  K: array[0..31of LongWord;
begin
  FillChar(K, SizeOf(K), 0);
  for I := 0 to 55 do
    if Data[DES_PC1[I] shr 3and ($80 shr (DES_PC1[I] and $07)) <> 0 then PC_M[I] := 1
      else PC_M[I] := 0;
  for I := 0 to 15 do
  begin
    if Reverse then M := (15 - I) shl 1
      else M := I shl 1;
    N := M + 1;
    for J := 0 to 27 do
    begin
      L := J + ROT[I];
      if L < 28 then PC_R[J] := PC_M[L] else PC_R[J] := PC_M[L - 28];
    end;
    for J := 28 to 55 do
    begin
      L := J + ROT[I];
      if L < 56 then PC_R[J] := PC_M[L] else PC_R[J] := PC_M[L - 28];
    end;
    L := $1000000;
    for J := 0 to 23 do
    begin
      L := L shr 1;
      if PC_R[DES_PC2[J     ]] <> 0 then K[M] := K[M] or L;
      if PC_R[DES_PC2[J + 24]] <> 0 then K[N] := K[N] or L;
    end;
  end;

  for I := 0 to 15 do
  begin
    M := I shl 1;
    N := M + 1;
    Key[0] := K[M] and $00FC0000 shl  6 or
              K[M] and $00000FC0 shl 10 or
              K[N] and $00FC0000 shr 10 or
              K[N] and $00000FC0 shr  6;
    Key[1] := K[M] and $0003F000 shl 12 or
              K[M] and $0000003F shl 16 or
              K[N] and $0003F000 shr  4 or
              K[N] and $0000003F;
    Key := @Key[2];      
  end;
end;


Und zwar ist es der gehighlightete Teil, welcher besonders zeitfressend ist. Und da diese Funktion aus der Datenbank ist und zweimal aufgerufen wird (einmal Reverse mit True und einmal mit False), denke ich nicht, dass dies noch gross optimierbar ist, da für Data und für Key immer wieder andere Werte kommen. So wies aussieht, ist das Projekt gescheitert :cry: Falls jemand noch eine Möglichkeit sieht, dies hier zu optimieren, darf er sie gerne anbringen.

Ein herzliches Dankeschön an alle, welche mich hier während dem Projekt mit ihren Tipps, Ratschlägen oder Demonstrationen unterstützt haben.
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 25.07.08 17:28 
ich wiederhole mich nur ungern, aber du solltest wirklich an deiner logik feilen, anstatt nur isoliert einzelne befehle zu betrachten.

ist schon klar, dass das markierte mehr zeit frist, als der restliche teil, da er sich ja in einer schleife befindet und ausserdem wieder schleifen enthält.

wie gesagt, war mein tipp hier vor ewigkeiten dass du versuchst, nur einmal die klasse aufzurufen und zu initialisieren. ansonsten solltest du versuchen, die routinen auseinanderzunehmen und die ergebnisse zwischenzuspeichern, damit du sie bei bedarf neu zusammenfügen kannst, ohne die daten neu zu berechnen.
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Fr 25.07.08 17:53 
Der Punkt ist doch einfach, dass du etwas machst was typischerweise nicht das erklärte Ziel einer solchen Verschlüsselung ist. Bist du schon mal auf die Idee gekommen, dass der Algorithmuss auch genau solche Sachen verhindern soll???

Und hier kommt eben genau zum Tragen was ich gesagt habe. Die Erstellung des Schlüssels ist sehr kostspielig, da die Ver und Entschlüsselung nun mal sehr schnell sein muss. Da typischerweise eben mehr Daten verschlüsselt werden als Schlüssel verdatet. Die Methode in Assambler umzuwandeln würde sicher etwas bringen. Von 23 Sekunden wirst du den Code auf 22,95 beschleunigen können. Der Code arbeitet nur mit fixen Strukturen etc. Das ist so aufgebaut, dass da kaum etwas zu machen ist. Der ist deswegen so langsam, da er nun mal sehr viel machen muss.

Das einzige wodurch du evtl etwas machen könntest, was auch nur ansatzweise sinnvoll wäre, wären Threads. Also auf Rechnern mit mehr als einem Prozessor dann mehr Berechnungen gleichzeitig durchführen. Alles andere wird vermutlich den Zeitaufwand nicht gerecht werden.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Fr 25.07.08 18:32 
user profile iconGrenzgaenger hat folgendes geschrieben:
ein ASM code lässt sich nicht inlinen, das ist eine der einschränkungen.

Abgesehen davon: Inline gibts glaub in D6 und D7 noch gar nicht, oder täusch ich mich?

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Tilman
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1405
Erhaltene Danke: 51

Win 7, Android
Turbo Delphi, Eclipse
BeitragVerfasst: Fr 25.07.08 18:38 
user profile iconGTA-Place hat folgendes geschrieben:

Abgesehen davon: Inline gibts glaub in D6 und D7 noch gar nicht, oder täusch ich mich?


Was macht denn inline überhaupt? In meiner D7-Hilfe steht "inline wird nur noch wegen der Abwärtskompatiblität beibehalten, und hat keinerlei auswirkung auf den Compiler".

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Fr 25.07.08 18:46 
user profile iconGrenzgaenger hat folgendes geschrieben:
ich wiederhole mich nur ungern, aber du solltest wirklich an deiner logik feilen, anstatt nur isoliert einzelne befehle zu betrachten.

ist schon klar, dass das markierte mehr zeit frist, als der restliche teil, da er sich ja in einer schleife befindet und ausserdem wieder schleifen enthält.

wie gesagt, war mein tipp hier vor ewigkeiten dass du versuchst, nur einmal die klasse aufzurufen und zu initialisieren. ansonsten solltest du versuchen, die routinen auseinanderzunehmen und die ergebnisse zwischenzuspeichern, damit du sie bei bedarf neu zusammenfügen kannst, ohne die daten neu zu berechnen.


Es ist mir durchaus klar, was du sagst. Aber das Ziel meiner Arbeit ist es, ein schnelles Programm und kein schönes zu haben. Das Programm war ursprünglich mal über 300 Sekunden langsam, und jetzt ist es auf 24. Ich habe die Sturkturen mal für mal durchgeschaut und wieder nach Verbesserungen gesucht. Ich habe Pointer verwendet, Pointer aus Pascal-Strings, Pointer auf normale Strings, die Daten in Arrays, die Daten direkt in den Strings, alles habe ich durchprobiert. Doch dann bin ich dort angekommen, wo ich nicht mehr wirklich sah, wie ich es noch grossartig verbessern könnte. Ebenfalls zeigten die Zeittests, dass der Teil, welchen ich geschrieben habe, ungefähr eine Sekunde einnimmt. Wenn ich das jetzt noch durch einen riesigen Aufwand halbieren könnte, schön und gut, doch das Ziel wird trotzdem weit gefehlt. Deshalb habe ich weitergesucht, was mir effektiv die Zeit frisst, und da stiess ich auf die vorhin genannte Funktion. Mir ist klar, dass die Logik stimmen muss und man mit den optimalen Parametern arbeiten sollte und alles. Jedoch habe ich festgestellt, wie eben erläutert, dass wirklich nur diese Funktion, welche in der Verschlüsselungsdatenbank ist, mir praktisch alle Zeit frisst. Dann kann ich an meiner Logik noch rumbasteln wie ich will, die Funktion bleibt gleich aufwendig und von da her komme ich auch nicht an die gewünschte Zeit ran. Von da her betrachte ich es, tut mir leid, wenn ich dir zunahe trete und so sehr ich auch Wert auf deine Tipps lege, als unnötig, hier noch an der Logik oder sonst etwas rumzuspielen, wenn ich ja eigentlich weiss, wo der fette Brocken sitzt und ich mir auch darüber im klaren bin, dass ich das wahrscheinlich nicht ändern kann.


user profile iconLossy eX hat folgendes geschrieben:
Der Punkt ist doch einfach, dass du etwas machst was typischerweise nicht das erklärte Ziel einer solchen Verschlüsselung ist. Bist du schon mal auf die Idee gekommen, dass der Algorithmuss auch genau solche Sachen verhindern soll???


Jep, genau daran habe ich auch gedacht, dass es nämlich absichtlich so gemacht wurde, da der Computer den Algorithmus nur einmal durchführen muss, und von da her könnte er sogar noch viel aufwendiger sein. Bemerkbar macht sich dies erst, wenn man es einige Male durchführen muss. Aber das ist wohl eine der Grundideen hinter dem Vorgang.


user profile iconLossy eX hat folgendes geschrieben:
Und hier kommt eben genau zum Tragen was ich gesagt habe. Die Erstellung des Schlüssels ist sehr kostspielig, da die Ver und Entschlüsselung nun mal sehr schnell sein muss. Da typischerweise eben mehr Daten verschlüsselt werden als Schlüssel verdatet. Die Methode in Assambler umzuwandeln würde sicher etwas bringen. Von 23 Sekunden wirst du den Code auf 22,95 beschleunigen können. Der Code arbeitet nur mit fixen Strukturen etc. Das ist so aufgebaut, dass da kaum etwas zu machen ist. Der ist deswegen so langsam, da er nun mal sehr viel machen muss.


Genau. Wie vorhin angesprochen, bringt es in meinen Augen nichts, einen minimalen Aufwand noch zu verringern, wenn man gegen den grossen chancenlos ist. Ob es 24 oder 23 Sekunden waren, interessiert am Ende dann niemanden mehr.



user profile iconLossy eX hat folgendes geschrieben:
Das einzige wodurch du evtl etwas machen könntest, was auch nur ansatzweise sinnvoll wäre, wären Threads. Also auf Rechnern mit mehr als einem Prozessor dann mehr Berechnungen gleichzeitig durchführen. Alles andere wird vermutlich den Zeitaufwand nicht gerecht werden.


An diesem PC hier habe ich einen Quad-Core. Heisst das, dass ich die Zeit auf 5-6 Sekunden reduzieren könnte? Wie müsste ich das genau anstellen?
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 25.07.08 18:46 
user profile iconGTA-Place hat folgendes geschrieben:
user profile iconGrenzgaenger hat folgendes geschrieben:
ein ASM code lässt sich nicht inlinen, das ist eine der einschränkungen.

Abgesehen davon: Inline gibts glaub in D6 und D7 noch gar nicht, oder täusch ich mich?


ist glaub ich 'n feature von D2006 ... ab da implementiert.

inline ist die delphi antwort auf 'n macro assembler bzw. auf macros. wo man den code einfach in routinen hineinkopiert, anstatt ihn aufzurufen. dadurch wird der code schneller, da er sich die ganzen overheads erspart.
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Sa 26.07.08 14:24 
Inline gabs früher mal (meine pascalzeiten). Und in Delphi 7 war das nutz- und wirkungslos. Allerdings mit neuerem Delphis (meine auch 2006) hat es wieder eine Wirkung bekommen. Und zwar sieht das so aus, dass der Code innerhalb einer Methode anstelle des Aufrufes kopiert wird. Es fällt also ein Funktionsausfruf weg, da der Code direkt dorthin kopiert wird. Bei kleinen Methoden die sehr häufig aufgerufen werden sparrt man durchaus einiges an Zeit.

Multithreads: Ich weiß nicht ob ich persönlich so viel interesse habe da so viel energie in dein Problem zu stecken.
www.opengl24.de/inde...;file=multithreading

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
walter_b Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 135

Windows Vista/XP
Delphi 6
BeitragVerfasst: Sa 26.07.08 17:15 
Super, vielen Dank. Jetzt bin ich im Moment auf 16.5 Sekunden mit 4 Threads (wegen Quad-Core). Viel mehr geht wohl nicht mehr, oder?