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

#592791
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
Angehängte Dateien:
Gast #592794
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.
Gast #592795
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.
Gast #592797
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.
Gast #592828
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.
#592908
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
Gast #592962
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
Gast #592963
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.
Gast #593007
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.
#593531
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
Gast #593561
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 $

Gast #593569
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.
Gast #593596
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ß.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren