Forum: PC-Programmierung GCC: Sehr langes C-Programm für Zielsystem PC


von Detlef _. (detlef_a)


Angehängte Dateien:

Lesenswert?

Hallo,

ich möchte angehängtes C-Programm, bestehend aus kurzem gcd.c und sehr 
langem, included vo.txt (5MB) mit GCC für nen Pentium target übersetzen. 
Das will mir nicht gelingen. Habe den GCC auf nem Windows-Rechner über 
mehrere Wege probiert: commandline von djgpp, Code::Blocks, commandline 
MingW. Das Ding terminiert ohne Warning (bei Code::Blocks offensichtlich 
mit exit-code 1), generiert aber nix.

Warum? Wie kriegt man GCC bißchen gesprächiger?

btw: Visual C generiert mit dem Ding 'internal Compiler Error'

Gute Nacht
Detlef

von Florian (Gast)


Lesenswert?

Unter Linux lässt es sich zumindest kompilieren (Verweis auf conio.h 
vorher entfernt):

chef@localhost /tmp/xyz $ date && gcc -c gcd.c && date
Fri Jun 29 01:26:09 CEST 2007
In Datei, eingefügt von gcd.c:15:
vo.txt:78751:6: Warnung: Kein Newline am Dateiende
Fri Jun 29 01:27:25 CEST 2007

Die Objekt-Datei ist etwas größer:
chef@localhost /tmp/xyz $ ls -lah gcd.o
-rw-r--r-- 1 chef chef 13M Jun 29 01:27 gcd.o

Dafür spuckt der Linker ein paar Fehler aus:
chef@localhost /tmp/xyz $ gcc -o gcd gcd.o 2>&1
gcd.o: In function `main':
gcd.c:(.text+0x1776): undefined reference to `pow'
gcd.c:(.text+0x1791): undefined reference to `pow'
gcd.c:(.text+0x17b4): undefined reference to `pow'
gcd.c:(.text+0x17da): undefined reference to `pow'
gcd.c:(.text+0x17fd): undefined reference to `pow'

Warnungen gibt es nur bzgl. unverwendeter Variablen:
chef@localhost /tmp/xyz $ gcc -c -fpie -Wall  gcd.c
In Datei, eingefügt von gcd.c:15:
vo.txt:78751:6: Warnung: Kein Newline am Dateiende
gcd.c: In Funktion »main«:
gcd.c:10: Warnung: Variable »b1za« wird nicht verwendet
gcd.c:10: Warnung: Variable »b1ya« wird nicht verwendet
gcd.c:10: Warnung: Variable »b1xa« wird nicht verwendet
gcd.c:10: Warnung: Variable »v0a« wird nicht verwendet
gcd.c:10: Warnung: Variable »b1z« wird nicht verwendet
gcd.c:10: Warnung: Variable »b1y« wird nicht verwendet
gcd.c:10: Warnung: Variable »b1x« wird nicht verwendet
gcd.c:9: Warnung: Variable »k« wird nicht verwendet

Das Problem ist vermutlich der Stack:

Hier ein Auszug aus dem über 100 MB großen Listing:
  28                    main:
  29 0000 8D4C2404              leal    4(%esp), %ecx
  30 0004 83E4F0                andl    $-16, %esp
  31 0007 FF71FC                pushl   -4(%ecx)
  32 000a 55                    pushl   %ebp
  33 000b 89E5                  movl    %esp, %ebp
  34 000d 53                    pushl   %ebx
  35 000e 51                    pushl   %ecx
  36 000f 81EC7090              subl    $1806448, %esp

Hier werden mal eben über 1 MB für den Stack freigeschaufelt.

von Florian (Gast)


Lesenswert?

Mit gcc -O9 -Wall -Wa,"ahl=list" gcd.c kommen jetzt noch mehr Warnungen:
vo.txt:1: Warnung: »s1« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »tf2« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »tf3« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »w2x« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »w3x« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »tf1« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »w1x« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »w1z« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »w1y« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »w2y« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »w2z« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »w3y« wird in dieser Funktion uninitialisiert 
verwendet
vo.txt:1: Warnung: »w3z« wird in dieser Funktion uninitialisiert 
verwendet

Mich hat nämlich verwundert, dass überhaupt sqrt aufgerufen wird, obwohl 
in einem Großteil des Listings direkt die Coprozessor-Befehle 
auftauchten. Mal sehen, was der Optimizer macht ---- das kann aber wohl 
noch dauern.

von Florian (Gast)


Lesenswert?

Hat leider auch nichts gebracht. Ich würde vorschlagen, dass Du Deinen 
Term in mehrere Zuweisungen aufspaltest. Vielleicht ist ja dann etwas zu 
machen. Das scheint ja auch sehr verschachtelt zu sein. Die Frage ist 
auch, ob man mathematisch nicht etwas vereinfachen könnte, aber über den 
Sinn dieses Ausdrucks kann ich mir kein Urteil erlauben, da ich mir das 
nicht wirklich angeschaut habe. Es sieht aber nach irgendeiner 
Matrizen-Operation aus.

von tex (Gast)


Lesenswert?

ein hübsches Monstrum. Ich würde das als Compiler auch nicht übersetzen 
wollen, zumal ich die freche Behauptung aufstelle, das sich in der 
vo.txt noch der eine oder andere Fehler verstecken könnte.

Ich würde Vorschlagen den Compiler etwas zu entlasten und immer 
wiederkehrende Therme  wie w1z*w2y*w3y erst einmal in Zwischenvariablen 
abzulegen, genau wie die ganzen pow - Therme

Dann kann es nicht schaden, noch ein paar überschaubare Zwiscehnschritte 
einzufügen

Zwischenwert = Zwischenwert + 
power(s1,2)*tf1*Power(tf2,2)*Power(tf3,2)*w1x*w2x*w2z;
Zwischenwert = Zwischenwert - 
2*Power(s1,2)*Power(tf1,2)*Power(tf2,2)*tf3*w1y*w2y*w2z;
Zwischenwert = Zwischenwert + 
2*Power(s1,2)*tf1*Power(tf2,2)*Power(tf3,2)*w1y*w2y*w2z;
Zwischenwert = Zwischenwert + 
2*Power(s1,2)*Power(tf1,2)*Power(tf2,2)*tf3*w1x*w1z*w3x;

Bei der Gelegenheit sieht man auch gleich, ob sich noch etwas 
vereinfachen läßt.
so kommt z.B. der Therm
2*Power(s1,2)*tf1*Power(tf2,2)*Power(tf3,2)*w1x*w2x*w2z +  weit über 200 
mal in Deiner Berechnung vor. Welchen Sinn soll es machen den uC das 200 
mal ausrechnen zu lassen, und ich habe bei 20 dieser Therme aufgehört zu 
suchen.
Also hier ist erst mal etwas Handarbeit in der Formel zu empfehlen.

von Detlef _. (detlef_a)


Lesenswert?

Hallo, danke für die posts und die Übersetzungsversuche, Florian.

>>gcd.c:(.text+0x1776): undefined reference to `pow'
'pow' is t doch plain C. math.h ist drin. Muß man nicht beim Linken 
explizit diese Mathelib einbinden?

>>o.txt:1: Warnung: »w3z« wird in dieser Funktion uninitialisiert
Ja, diese Variablen sind alle noch uniniatilisiert. Mact#ht aber nix, 
erstmal muß das Monster übersetztbar sein.

Die Source ist automatisch erzeugt von Mathematica, wenn ich da händisch 
fummele baue ich erst Fehler ein, jetzt sollte das fehlerfrei sein. 
Vereinfachung ist also erstmal nicht (Simplify[] von Mathematice steigt 
bei dem Term auch aus)

Ich brauche von dem Ding ne .exe fürn PC. Die kann ruhig groß sein und 
unoptimiert, Hauptsache ich kriege den Brocken kompiliert.

Cheers
Detlef

von Bartli (Gast)


Lesenswert?

Also bei mir kompiliert das Dingens und generiert ein Programm, welches

blblabbbb

ausgibt.

Kompiliert mit "gcc gcd.c -o gcd -lm -Wall", gcc version ist 4.1.2 
irgendwas.

gcd.c:7: warning: return type defaults to ‘int’
In file included from gcd.c:14:
vo.txt:78751:6: warning: no newline at end of file
gcd.c: In function ‘main’:
gcd.c:9: warning: unused variable ‘b1za’
gcd.c:9: warning: unused variable ‘b1ya’
gcd.c:9: warning: unused variable ‘b1xa’
gcd.c:9: warning: unused variable ‘v0a’
gcd.c:9: warning: unused variable ‘b1z’
gcd.c:9: warning: unused variable ‘b1y’
gcd.c:9: warning: unused variable ‘b1x’
gcd.c:8: warning: unused variable ‘k’
gcd.c:17: warning: control reaches end of non-void function

von Florian (Gast)


Lesenswert?

Das Problem ist, dass mein Compiler pow und sqrt als inline ablegt und 
die tief verschachtelten Dinger dann wohl aufgrund irgendwelcher 
Constraints doch als Funktion aufrufen wollte. Diese Funktion gibt es 
aber nicht als externe Funktion; davon gehe ich zumindest aus.

Vielleicht komme ich heute im Laufe des Tages dazu, die Funktion 
auseinaderzunehmen, d.h. zumindest die Klammertiefe zu verringern 
(natürlich nicht per Hand. Vielleicht hilft dem Compiler das schon.

Ich darf jetzt erst einmal meine Post vom Schalter abholen, da der 
Postbote wohl zu faul war, meine Post zu schleppen.

von Florian (Gast)


Lesenswert?

> Also bei mir kompiliert das Dingens und generiert ein Programm

Oh, ich muss mir an den Kopf fassen. Es war das -lm. Richtig, da sind 
sqrt und pow drin.

von tex (Gast)


Lesenswert?

nun ja ,eine Formel die nur 4,493 MB im Arbeitsspeicher braucht, ohne 
Rechenoperationen, das wird ein lustige EXE werden ... ;-)
Na mach mal, und sag uns was dabei rausgekommen ist ;-)

von Bartli (Gast)


Lesenswert?

Schieb mal Werte rüber, um die Variablen zu initialisieren, mal schauen 
was rauskommt dabei...

von Detlef _. (detlef_a)


Lesenswert?

> Also bei mir kompiliert das Dingens und generiert ein Programm

Super. Gelang das auf nem Linux System? Linux kann ich selbst nicht 
probieren, habe hier GCC unter Windows laufen.

Cheers
Detlef

von Detlef _. (detlef_a)


Lesenswert?

>>Schieb mal Werte rüber, um die Variablen zu initialisieren, mal schauen
>>was rauskommt dabei...

Initialisier sie doch bitte selber und schick die Initilisierung und das 
Ergebnis. Prüfen kann ich das dann anhand des Gleichungssystems.


Cheers
Detlef

von Bartli (Gast)


Lesenswert?

Ja. Aber probier sonst mal ne neuere gcc version, vielleicht liegts ja 
nur daran.

von Detlef _. (detlef_a)


Lesenswert?

Hab ne 4.1.2

Cheers
Detlef

von Bartli (Gast)


Lesenswert?

Mmmkay...hab alle variablen mit 0 initialisiert, und raus kommt...

nan

Ok...da wird durch s1 dividiert, also sollte man vielleicht s1 nicht mit 
0 initialisieren, aber andererseits müsste dann + oder - inf rauskommen 
und nicht nan...also...s1 mit 1 initialisiert, und raus kommt...

nan

Evtl. kannst du das gar nicht blindlings mit double durchrechnen, oder 
der generierte Code funkt nicht.

von Simon K. (simon) Benutzerseite


Lesenswert?

tex wrote:
> nun ja ,eine Formel die nur 4,493 MB im Arbeitsspeicher braucht, ohne
> Rechenoperationen, das wird ein lustige EXE werden ... ;-)
> Na mach mal, und sag uns was dabei rausgekommen ist ;-)

Ist das deine einzige Sorge bei heutzutagigen 2GB Arbeitsspeicher? ;)

von Karl H. (kbuchegg)


Lesenswert?

Bei der Formel wird alles Mögliche rauskommen, nur
kein einigermassen korrektes Ergebnis. Du erwartest
zuviel von double. Ohne ein System, welches sowas
exakt berechnen kann, hat das wenig bis gar keinen
Sinn weil dich die Rundungsungenauigkeiten umbringen
werden.

von Detlef _. (detlef_a)


Lesenswert?

Ähm, ja, die Initialisierungen sind natürlich nicht beliebig, sonst muß 
man ne Wurzel aus ner negativen Zahl ziehen. Ich mache heute abend nen 
Datensatz zum  Testen klar und poste den.

Bartli, läuft das Programm unter Linux oder Windows?

Cheers
Detlef

von Bartli (Gast)


Lesenswert?

Linux. Aber hör auf Karl Heinz: vermutlich hats eh keinen Sinn :D

von Bartli (Gast)


Lesenswert?

> Ähm, ja, die Initialisierungen sind natürlich nicht beliebig, sonst muß
> man ne Wurzel aus ner negativen Zahl ziehen.

Das würde die nans erklären.

von Detlef _. (detlef_a)


Lesenswert?

Hallo,

habe es hingekriegt, es geht. Ermutigt durch den Ratschlag, das zu 
vereinfachen habe ich Mathematika heute nochmal ackern lassen und dabei 
ist tatsächlich eine Formel rausgekommen, die nur noch 2.2MB anstatt 
5.5MB lang ist. Die schluckt mein GCC (4.1.2 mit Code::Blocks) und macht 
da ne wunderbare .exe raus. Und das Schönste: Es kommt was Richtiges 
raus: 3.4568..e2 (naja, almost, richtig richtig wäre 3.433742e+002).

Die Genauigkeit muß ich noch ausloten, aber erstmal geht das. Karl 
heinz' Einwand zur Genauigkeit ist nicht von der Hand zu weisen. Aber es 
gibt natürlich Iterationen, bei denen öfter multipliziert/addiert wird 
als in dieser Formel und trotzdem was richtiges rauskommt. Oft 
hintereinander mul/add heißt ja nicht, daß das Ergebnis immer ungenauer 
wird. Fortpflanzung von Rechenfehlern ist ne harte Kiste, aber hier hats 
geklappt. Außerdem war der Einwand eher Motivation, es trotzdem zu 
probieren.

Testfile mit Datensatz und kürzeres Include File habe ich angehängt. 
Würde mich sehr interessieren, ob die Ursprungsformel auch funzt.

Danke an alle Mitwirkenden.

Cheers
Detlef

von Detlef _. (detlef_a)


Angehängte Dateien:

Lesenswert?

Mist Anhang vajessen. hier

Cheers
Detlefe

von Bartli (Gast)


Lesenswert?

Kann ich frühestens Montags testen, falls ich dann noch dran denke.

von Florian (Gast)


Lesenswert?

gcd.c:2:19: Fehler: conio.h: Datei oder Verzeichnis nicht gefunden
gcd.c:8: Warnung: Rückgabetyp ist auf »int« voreingestellt
In Datei, eingefügt von gcd.c:33:
cal1a.txt:28887:17: Warnung: Kein Newline am Dateiende
gcd.c: In Funktion »main«:
gcd.c:9: Warnung: Variable »k« wird nicht verwendet
gcd.c:36: Warnung: Kontrollfluss erreicht Ende einer Nicht-void-Funktion


Ein paar Änderungen, d.h. conio.h auskommentiert, int vor main 
eingefügt, einen Wert zurückgegeben und einen Zeilenumbruch in cal1a.txt 
eingefügt:

chef@localhost /tmp $ date && gcc -o gcd -Wall -lm gcd.c && date
Fri Jun 29 20:45:04 CEST 2007
gcd.c: In Funktion »main«:
gcd.c:9: Warnung: Variable »k« wird nicht verwendet
Fri Jun 29 20:45:21 CEST 2007
chef@localhost /tmp $ date && ./gcd && date
Fri Jun 29 20:45:38 CEST 2007
 3.456838e+02
Fri Jun 29 20:45:38 CEST 2007
chef@localhost /tmp $


von Florian (Gast)


Lesenswert?

Für genauere Ergebnisse könntest Du ggf. die GMP-Library benutzen und 
einen Floating-Point-Typ mit höherer Breite wählen.

http://gmplib.org/

Das würde allerdings bedeuten, dass Du vorher Deinen Ausdruck umwandeln 
müsstest. Für den interessierten Hobby-Programmierer wäre dann z.B. YACC 
angesagt, aber hier würde es wohl auch noch mit einem Perl-Script getan 
sein, den Ausdruck umzubauen.

von Wiesi (Gast)


Lesenswert?

Zwecks der Genauigkeit fällt mir da spontan GMP ein (http://gmplib.org/)

Ist eine Lib für beliebige Rechengenauigkeit und hoch optimiert. Wenn 
man
irgendwie einfache Wrapper machen könnte, damit die benutzt wird, sollte 
es besser werden.

  Wiesi

von PS (Gast)


Lesenswert?

Ich habe das Programm mal mit gcc 4.3 20070615 (experimental) getestet.
GCC 4.3 ist in der Lage, Aufrufe von Math-Funktionen mit konstanten
Argumenten zur Kompilierzeit zu berechnen. Dazu verwendet GCC die
MPFR Library (http://www.mpfr.org).

Das kommt dabei heraus:
1
08048390 <main>:
2
 8048390:       8d 4c 24 04             lea    0x4(%esp),%ecx
3
 8048394:       83 e4 f0                and    $0xfffffff0,%esp
4
 8048397:       ff 71 fc                pushl  0xfffffffc(%ecx)
5
 804839a:       55                      push   %ebp
6
 804839b:       51                      push   %ecx
7
 804839c:       83 ec 14                sub    $0x14,%esp
8
 804839f:       c7 44 24 04 83 45 00    movl   $0xe5004583,0x4(%esp)
9
 80483a6:       e5
10
 80483a7:       c7 44 24 08 f0 9a 75    movl   $0x40759af0,0x8(%esp)
11
 80483ae:       40
12
 80483af:       c7 04 24 d0 84 04 08    movl   $0x80484d0,(%esp)
13
 80483b6:       e8 d5 fe ff ff          call   8048290 <printf@plt>
14
 80483bb:       83 c4 14                add    $0x14,%esp
15
 80483be:       59                      pop    %ecx
16
 80483bf:       5d                      pop    %ebp
17
 80483c0:       8d 61 fc                lea    0xfffffffc(%ecx),%esp
18
 80483c3:       c3                      ret

Ergebnis:
1
./gcd
2
 3.456838e+02
Das ausführbare Programm (Linux) ist übrigens insgesamt 7044 Bytes groß.

von mr.chip (Gast)


Lesenswert?

Darf ich mal fragen...was soll das? :-)

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
Noch kein Account? Hier anmelden.