"Keine Rückmeldung" vermeiden

Wohl das A & O in der Windows-Programmierung

Moderatoren: crack, Krüsty, Marwin

"Keine Rückmeldung" vermeiden

Beitragvon Biehler-Productions » Samstag 20. Mai 2006, 09:48

Hi,
ich arbeite gerade an einer DLL, mit der man theoretisch unendlich lange Zahlen bearbeiten kann.
Ich hab nun 2 Funktionen, die (scheinbar) ausnahmslos funktionieren.
Addieren und Subtrahieren.
Projekt-Page ( http://biehlcomp.biehler-josef.de ) ist auch schon online.
Nur heut ist mir erst gekommen: Was bringt mir eine Multiplikationfunkton, die unendlich lange Zahlen verarbeiten KÖNNTE, wenn es die Maschine nicht packt?
Eine Multiplikation baut ja auf unzähligen Additionen auf.
Ich habe also die Additionsfunktion 0FFFFFFFF mal aufrufen lassen (in einer Schleife).
Das Ergebnis war alles andere als erfreulich.
Ich brach nach einiger Zeit ab, da das Programm scheinbar immer noch rechnete.

Nun 2 Fragen:
wenn ich den Taskmanager aufrufe, erscheint bei dem programm "Keine RÜckmeldung".
Bei Delphi gab es einen Befehl, mit der man dieses unterbinden konnte.
Das Programm konnte dadurch auch in einer langen Schleife noch Aktionen entgegen nehmen.
Wiew heiußt dieser befehl in der WinAPI bzw. in Assembler?
Mir fällt leider der Befehl in Delphi auch nicht mehr ein :(

2.:
Ich denke die ganze Zeit, dass dieses Projekt ja praktisch sinnlos ist, da man zwar unendlich lange Zahlen berechnen könnte, aber es niemanden etwas nützt, da es einfach zu lange dauert.
Die einzigen FUnktionen, die sinnvoll sind, sind Addition und Subtraktion.
Aber sobald es an die Multiplikation/Division geht, dauert es einfach zu lange.
Sollte ich das Projekt aufgeben?
bzw. wart ihr schonmal in so einer Situation?
Keiner wird diese FUnktionen benutzen, da
1.
Wohl fast keiner sehr lange Zahlen bearbeiten muss
und
2.
Keiner 50 Minuten warten will, bis er weis, was 68719476735 * 68719476735 ist, wenn er das mit dem Windows Rechner auch machen kann und der nur 1 Sekunde braucht.
mfg
Biehler-Productions
http://biehler-josef.de
Biehler-Productions
Member
 
Beiträge: 18
Registriert: Freitag 21. April 2006, 12:39

Beitragvon Marwin » Samstag 20. Mai 2006, 18:55

Hallo,

zuerst zum letzten Punkt. Wenn der Windows Taschenrechner diese Aufgabe in 1 Sekunde bearbeiten kann, während deine DLL 50 Minuten benötigt, dann ist dein Algorithmus anscheinend äußerst einfach gehalten. Aus meiner Sicht würde es Sinn machen, wenn man sich über den Algorithmus Gedanken macht.

"Wohl fast keiner" ... Nun, das trifft so nicht zu. Es ist wohl richtig, dass die meisten informatischen Probleme ohne unendlich große Zahlen gelöst werden können. Ich bin aber überzeugt, dass es vor allem im Bereich der Forschung diverse Anwendungsgebiete gibt, bei denen eine extreme Genauigkeit wichtig oder zumindest interessant ist. Lösungen dafür sind mir im Moment nicht bekannt, mit Sicherheit gibt es welche. Das allein sollte dich aber nicht von deinem Projekt abbringen.

Grüße,
Marwin
Benutzeravatar
Marwin
Moderator
 
Beiträge: 307
Registriert: Donnerstag 8. Mai 2003, 21:19
Wohnort: Seelow, Deutschland

Beitragvon CDW » Samstag 20. Mai 2006, 19:45

mich würde der Algo auch interessieren -denn diesen optimiert man als erstes. Zwar fällt mir die Multiplikation im Moment nicht ein (zumindest geeignete Methode ;) ) aber Addition könnte man ganz bequem durchführen in dem man die Zahl in Maschinenwords unterteilt und jeweils beim Addieren den Übertrag berücksichtigt. Wobei man sich dann eine geeignete Zahlendarstellung überlegen sollte. Bei dem x86 System würde ich so vorgehen:

Zahl1: 01234567 89101112 3456789
Zahl2 02456789 13254678 1233213

einfache Addition:
- jeweils eine Registerbreite (also 4 Byte) am Ende nehmen und addieren.
- dabei den Carryflag berücksichtigen (die nächste Instruktion könnte ein ADC sein oder ähnlich).
dann die nachfolgenden 4 Bytes nehemen und addieren usw.
Am ende nochmal den Carry berücksichtigen

Bei vorzeichenbehafteten Operationen muss man noch den Overflowflag beachten.


Zur Multiplikation: man könnte hier mit SHIFT arbeiten (eigenimplementierung), die schriftliche Multiplikation nachbilden oder bei google nach einem "echten" verfahren suchen ;)
CDW
Alter Hase
 
Beiträge: 62
Registriert: Donnerstag 2. Oktober 2003, 17:17

Beitragvon Biehler-Productions » Samstag 20. Mai 2006, 22:14

@Marwin
Gut, der Win Rechner benötigt dafür eine Sekunde, da er wahrscheinlich die FPU benutzt.
Die 50Minuten waren nur bildlich gesprochen, gemessen hab ich die noch nicht.

Als zum Algo:
Ich bilde eigentlich die Schriftliche Addition und Subtraktion nach.

Bei der Divison wollte ich zuerst ebenfalls die schriftliche Variante nachbilden, aber dann wusste ich nicht, wie ich Zahlen größer als 32Bit verarbeiten kann.
Deshalb impletiere ich die Division als eine Folge von Subtraktionen und die Multiplikation als eine Folge von Additionen.

btw
ich hab ein weiteres Problem mit der DLL:
Ich bin mir überhaupt nicht sicher, ob man in anderen Programmiersprachen die DLL benutzen kann.
Weil ich verwende in der DLL den STDCALL Aufruf, C verwendet ja einen anderen.
Kommt es da nicht zu Komplikationen, oder ist eine DLL streng standarisiert?
mfg
Biehler-Productions
http://biehler-josef.de
Biehler-Productions
Member
 
Beiträge: 18
Registriert: Freitag 21. April 2006, 12:39

Beitragvon Marwin » Sonntag 21. Mai 2006, 01:08

Das ist richtig. C und C++ verwenden CDECL, während z.B. die Windows API mit STDCALL "arbeitet". In C++ gibt es aber die Möglichkeit beim Angeben des Prototypen auch die Konvention festzulegen. Der Compiler beachtet dies dann beim erstellen des ausführbaren Codes.
Diese Möglichkeit wird es sicher auch bei anderen Programmiersprachen geben, die die Verwendung fremder DLLs erlauben.

Eine Möglichkeit, um das Problem "Keine Rückmeldung" zu umgehen ist, den Algorithmus in einem anderen Thread auszuführen, so dass die WinMain zu jeder Zeit auf die Messages des Betriebssystems reagieren kann.
Benutzeravatar
Marwin
Moderator
 
Beiträge: 307
Registriert: Donnerstag 8. Mai 2003, 21:19
Wohnort: Seelow, Deutschland

Beitragvon Biehler-Productions » Sonntag 21. Mai 2006, 09:46

OK.
Kann hier jemand C?
Ich bräuchte dann nämlich einen Codeschnippsel, der eine Funktion aus einer fremden DLL aufruft.

Ich les mich gerade erst in C ein, kann das also leider noch nicht selber.

Ich hab mir gedacht, das ich mit LoadLibrary und GetProcAdresse arbeiten könnte, aber dann wusste ich nicht, wie ich dann mit C an die Adresse springen kann, die in EAX zurückgegeben wird.
mfg
Biehler-Productions
http://biehler-josef.de
Biehler-Productions
Member
 
Beiträge: 18
Registriert: Freitag 21. April 2006, 12:39

Beitragvon crack » Montag 22. Mai 2006, 09:33

Mal ne Idee meinerseits (wenn unpraktikabel bitte verwerfen :lol: ), wie wäre es wenn die DLL eine Fallunterscheidung durchführt?
1. bis 32bit Integer - kann der Proz. berechnen
2. bis 80bit Integer oder Real - hier wird an CoPro Übergeben
3. über 80bit Int. (oder evtl. Real) - wird mittels der beschriebenen Algorythmen berechnet
4. 'fast unendlich gross' - es wir eine Grenzwertberechnung durchgeführt

greetz crack 8)
mit freundlichen grüssen,
with best regards,

crack
Benutzeravatar
crack
Administrator
 
Beiträge: 280
Registriert: Dienstag 21. Dezember 2004, 15:02
Wohnort: 53783 Eitorf

Beitragvon Biehler-Productions » Montag 22. Mai 2006, 14:16

@crack
Nein, so schlecht ist ide Idee nicht, aber ich hatte die schon selber (zumindest so ähnlich) :lol:

Ich werde keine Fal,lunterscheidung machen, sondern verschiedene Funktionen bereitstellen.
Also eine für ganz normale 8/16/32 Bit, eine für Zahlen > 32Bit (FPU) und größer als die FPU Register dann mit meinem Algo.
Aber ich hab mir bereits Gedanken gemacht zum optimieren.
Wenn ich statt einem einzelnen BYte jeweils 4 Byte addiere/subtrahiere, hätte ich einen Geschwindigkeitsfalktor x4
Und ich hab mir mal ausgerechnet, wenn ich 1 ms einsparen könnte, könnte ich bei der Multiplikation von 1000000 * 1000000 eine VIERTEL Stunde sparen(!)

//EDIT:
@Marwin

Ich dachte C und C++ benutzen die C Callng Konvention?

Ich muss also praktischerweise entwder für jeden Aufrufstandard eine eigene Funktion impletieren oder in der README darauf hinweisen, dass ich den STDCALL Standard verwende?

//EDIT:
Dieser CDECL ist doch der normale C Standard, oder?
mfg
Biehler-Productions
http://biehler-josef.de
Biehler-Productions
Member
 
Beiträge: 18
Registriert: Freitag 21. April 2006, 12:39

Beitragvon Marwin » Montag 22. Mai 2006, 22:48

Biehler-Productions hat geschrieben:Ich dachte C und C++ benutzen die C Callng Konvention?
//EDIT:
Dieser CDECL ist doch der normale C Standard, oder?


richtig


in der README darauf hinweisen, dass ich den STDCALL Standard verwende?


Wie schon gesagt ist STDCALL der Standard unter Windows. Du kannst natürlich dennoch zusätzlich darauf hinweisen.
Benutzeravatar
Marwin
Moderator
 
Beiträge: 307
Registriert: Donnerstag 8. Mai 2003, 21:19
Wohnort: Seelow, Deutschland

Beitragvon crack » Dienstag 23. Mai 2006, 02:57

Diese Aufruf Konventionen kannst Du in der MASM32 Help unter:
MASM Reference / Calling Conventions finden.

Zur Optimierung der Programmlaufzeit (vll erzähle ich dir nix neues, aber manchem ist das evtl. nicht bekannt):
es ist vermutlich günstiger mit den puren jmp, jz, jnz, jg usw. und cmp Anweisungen zu arbeiten, als .if .elseif .endif Konstruktionen zu benutzen denn eine
...
.if eax == 0
code1
.endif
code2
...

erzeugt idR folgendes:
...
cmp eax,0
jnz Label1
jmp Label2
Label1:
code1
Label2:
code2
...
zeitlich günstiger ist es da unmittelbar folgendes zu proggen:
...
cmp eax,0
jz Label2
code1
Label2:
code2
...

so kann man bei Schleifen die häufig durchlaufen werden eine ganze Menge Laufzeit sparen, und was noch recht interessant ist (kann sein das es mittlerweile auch anders ist...) ich habe früher einmal festgestellt das die Verwendung von Speichervariablen im Gegensatz zum Push und Pop auch einen Erheblichen Zeitgewinngebracht hat.
mit freundlichen grüssen,
with best regards,

crack
Benutzeravatar
crack
Administrator
 
Beiträge: 280
Registriert: Dienstag 21. Dezember 2004, 15:02
Wohnort: 53783 Eitorf


Zurück zu Windows-API

 


  • { RELATED_TOPICS }
    Antworten
    Zugriffe
    Letzter Beitrag

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder

cron