Hallo Sprinter (schreibe mal hier)
In Formeln bin ich sehr schlecht, aber was hälst DU davon, wenn man dazu fixe Werte für die Variablen verwendet, einen Einheitlichen Prozessor (z.B. den Mega8) und einen Gleichbeleibenden Quarz. Dann könnte man die Codes auch untereinander in der Ausführungszeit und dem Speicherverbrauch vergleichen..? Mann müsste dann aber auch den kompletten Code aufzeigen... (für C alle Libs..)--Roberto 22:31, 6. Apr 2006 (CEST)
Die C-Codes habe ich für einen ATmega8 übersetzt. Die Einstellungen für den CPU-Takt haben keinen Einfluss auf die Codeerzeugung (oder etwa bei Bascom??). Den Flash-Verbrauch kann man abzählen oder anzeigen lassen, Zeit- und RAM-Verbrauch sind statisch bestimmbar – letzeres ist allerdings etwas Arbeit.
Die Beispiele habe ich als einfache Funktionen gewählt. Einerseits, weil man da schon viel der Eigenheiten eines Compilers erkennen kann. Der erzeugte Code ist wie ein Fingerabdruck und exemplarisch für größere Beispiele. Zudem finde ich, das große Beispiele nicht viel mehr aussagen, und durch meterlange Listings steigt niemand durch und langweilen eher.
Zudem habe ich Beispiele gewählt, die keine Bibliotheken brauchen. Mehr als der Code, der da steht, wird nicht ausgeführt und ist irrelevant, also auch, wie es "ausserhalb" der Funktionen aussieht. Der einzige externe Bezug ist die Funktion foo() bei den Interrupt-Routinen. Welcher Code sich dahinter verbirgt ist egal. Es ist einfach irgendeine parameterlose Funktion ohne Rückgabewert, die irgendwas macht und dann zurückkehrt. Genauso ist die Code, aus denen die Beispiele aufgerufen werden, für die Übersetzung unerheblich. Es sind ja keine statischen oder inline-Funktionen.
--SprinterSB 23:20, 6. Apr 2006 (CEST)
sum_n_loop
Ich hab mal einen Code in Bascom reingestellt. Ich glaube nicht dass Dir das Endergebnis so zusagt. Ist das Ergebnis 45 bei 10 Durchläufen korrekt?? Falls doch, gib mir per PM bescheid, dann mach ich ggf. mehr.
--Darwin.nuernberg 21:43, 23. Apr 2006 (CEST)--Darwin.nuernberg 21:43, 23. Apr 2006 (CEST)
Am hex-File sieht man leider nicht viel, weil da vermutlich das genze Programm drinne ist und noch StartUp-Code und so.
Ich hab mir mal in BASCOM geschaut, aber auf Anhieb hab ich nix gesehen, wie man an den Assembler-Code kommt.
Hier mal ein Disassemble deines iHex:
Disassembly of section .sec1: 00000000 <.sec1>: 0: 12 c0 rjmp .+36 ; 0x26 2: 18 95 reti 4: 18 95 reti 6: 18 95 reti 8: 18 95 reti a: 18 95 reti c: 18 95 reti e: 18 95 reti 10: 18 95 reti 12: 18 95 reti 14: 18 95 reti 16: 18 95 reti 18: 18 95 reti 1a: 18 95 reti 1c: 18 95 reti 1e: 18 95 reti 20: 18 95 reti 22: 18 95 reti 24: 18 95 reti 26: 8f e5 ldi r24, 0x5F ; 95 28: 8d bf out 0x3d, r24 ; 61 2a: c0 e4 ldi r28, 0x40 ; 64 2c: e8 e3 ldi r30, 0x38 ; 56 2e: 4e 2e mov r4, r30 30: 84 e0 ldi r24, 0x04 ; 4 32: 8e bf out 0x3e, r24 ; 62 34: d4 e0 ldi r29, 0x04 ; 4 36: f4 e0 ldi r31, 0x04 ; 4 38: 5f 2e mov r5, r31 3a: ee ef ldi r30, 0xFE ; 254 3c: f3 e0 ldi r31, 0x03 ; 3 3e: a0 e6 ldi r26, 0x60 ; 96 40: b0 e0 ldi r27, 0x00 ; 0 42: 88 27 eor r24, r24 44: 8d 93 st X+, r24 46: 31 97 sbiw r30, 0x01 ; 1 48: e9 f7 brne .-6 ; 0x44 4a: 66 24 eor r6, r6 4c: e0 e6 ldi r30, 0x60 ; 96 4e: f0 e0 ldi r31, 0x00 ; 0 50: fa 93 st -Y, r31 52: ea 93 st -Y, r30 54: 5a 92 st -Y, r5 56: 4a 92 st -Y, r4 58: 8a e0 ldi r24, 0x0A ; 10 5a: 90 e0 ldi r25, 0x00 ; 0 5c: a4 2d mov r26, r4 5e: b5 2d mov r27, r5 60: 8d 93 st X+, r24 62: 9c 93 st X, r25 64: 82 e0 ldi r24, 0x02 ; 2 66: 35 d0 rcall .+106 ; 0xd2 68: 05 d0 rcall .+10 ; 0x74 6a: 24 96 adiw r28, 0x04 ; 4 6c: 82 e0 ldi r24, 0x02 ; 2 6e: 2d d0 rcall .+90 ; 0xca 70: f8 94 cli 72: ff cf rjmp .-2 ; 0x72 74: a8 81 ld r26, Y 76: b9 81 ldd r27, Y+1 ; 0x01 78: 8d 91 ld r24, X+ 7a: 9c 91 ld r25, X 7c: a2 e6 ldi r26, 0x62 ; 98 7e: b0 e0 ldi r27, 0x00 ; 0 80: 8d 93 st X+, r24 82: 9c 93 st X, r25 84: aa 81 ldd r26, Y+2 ; 0x02 86: bb 81 ldd r27, Y+3 ; 0x03 88: 37 d0 rcall .+110 ; 0xf8 8a: a2 e6 ldi r26, 0x62 ; 98 8c: b0 e0 ldi r27, 0x00 ; 0 8e: 0d 91 ld r16, X+ 90: 1c 91 ld r17, X 92: 00 30 cpi r16, 0x00 ; 0 94: 50 e0 ldi r21, 0x00 ; 0 96: 15 07 cpc r17, r21 98: 14 f0 brlt .+4 ; 0x9e 9a: 09 f0 breq .+2 ; 0x9e 9c: 01 c0 rjmp .+2 ; 0xa0 9e: 12 c0 rjmp .+36 ; 0xc4 a0: a2 e6 ldi r26, 0x62 ; 98 a2: b0 e0 ldi r27, 0x00 ; 0 a4: 1a d0 rcall .+52 ; 0xda a6: aa 81 ldd r26, Y+2 ; 0x02 a8: bb 81 ldd r27, Y+3 ; 0x03 aa: 0d 91 ld r16, X+ ac: 1c 91 ld r17, X ae: a2 e6 ldi r26, 0x62 ; 98 b0: b0 e0 ldi r27, 0x00 ; 0 b2: 4d 91 ld r20, X+ b4: 5c 91 ld r21, X b6: 04 0f add r16, r20 b8: 15 1f adc r17, r21 ba: aa 81 ldd r26, Y+2 ; 0x02 bc: bb 81 ldd r27, Y+3 ; 0x03 be: 0d 93 st X+, r16 c0: 1c 93 st X, r17 c2: e3 cf rjmp .-58 ; 0x8a c4: 08 95 ret c6: f8 94 cli c8: ff cf rjmp .-2 ; 0xc8 ca: 48 1a sub r4, r24 cc: 88 27 eor r24, r24 ce: 58 0a sbc r5, r24 d0: 08 95 ret d2: 48 0e add r4, r24 d4: 88 27 eor r24, r24 d6: 58 1e adc r5, r24 d8: 08 95 ret da: ed 91 ld r30, X+ dc: fc 91 ld r31, X de: 31 97 sbiw r30, 0x01 ; 1 e0: fc 93 st X, r31 e2: ee 93 st -X, r30 e4: 08 95 ret e6: 31 97 sbiw r30, 0x01 ; 1 e8: f1 f7 brne .-4 ; 0xe6 ea: 08 95 ret ec: 68 94 set ee: 62 f8 bld r6, 2 f0: 08 95 ret f2: e8 94 clt f4: 62 f8 bld r6, 2 f6: 08 95 ret f8: 82 e0 ldi r24, 0x02 ; 2 fa: 01 c0 rjmp .+2 ; 0xfe fc: 84 e0 ldi r24, 0x04 ; 4 fe: 99 27 eor r25, r25 100: 9d 93 st X+, r25 102: 8a 95 dec r24 104: e9 f7 brne .-6 ; 0x100 106: 08 95 ret
ihex ist leider ein absolutes low-Level-Format, ohne jegliche Symbolinformation...
Es ist ein ganzes ausführbares Prog, enthält also ausser der Funktion noch zusätzlichen Code und mehr als nur die Funktion:
0x0000 -- 0x0024: VecTab 0x0026 -- 0x????: Startup-Code 0x???? -- 0x????: Hauptprogramm 0x0058(?) -- 0x006a :X = Sum_n_loop(10) 0x006c - 0x0072: End 0x0074--0x00c4: Sum_n_loop 0x00ca: Helper 0x00da: Helper 0x00d2: Helper 0x00f8: Helper
Die Helper sind kleine Funktionen, die auf dem Stack und BASCOM-internen GPRs operieren. Zumindest was ich auf die schnelle sehe. Ich kenne BASCOM wie gesagt nicht.
1+2+3+4+5+6+7+8+9+10 = 55
Deine 45 kommt daher, daß das Decr zu früh gemacht wird. Es berechnet also nut die Summe 1...N-1.
Jemand mit besserer Kenntnis von BASCOM könnte den Spaghetti-Code besser auseinanderklabüstern als ich.
Die Helper gehören eigentlich nicht zum Code der Funktion, auch wenn sie teilweise von dort aufgerufen werden. Bei mehreren Funktionen werden die anderen Funks die SChnippsel auch benutzen, so daß der Code nicht der Summation zuzuschlagen ist (find ich jedenfalls).
--SprinterSB 23:07, 23. Apr 2006 (CEST)
Problem bei BASCOM ist, dass es nicht compiliert, wenn der Code nicht ausführbar ist. Ein Objectfile oder sowas wird nicht generiert, ist ja kein C oder Pascal oder sowas. Also ein Vergleich ist wenn überhaupt am endgültigen Resultat, sprich HEX-File möglich. Aber das hattest Du vermutlich nicht vor. Das mit der Korrektur des Schleifendurchlauf es wäre kein akt, aber wenn Du das Endresultat nicht zum Vergleich heranziehen willst, macht es keinen Sinn da noch weitere Energie hinein zu stecken. EIgentlich wäre anstelle "While I > 0" nuer ein "While I >= 0" nötig um die Funktion korrekt zum Ende zu bringen.
PS: wo ist das denn ein Spagetti-Code? Ist doch schön strukturiert. Nur weil Du die Befehle nicht kennst muss es doch kein Spagetticode sein. Und so schlimm ist es wohl auch nicht. Umgekehrt könnte ich zu C Spagetti sagen, weil mir das nicht zusagt.
--Darwin.nuernberg 00:28, 24. Apr 2006 (CEST)
Mich interessiert der Vergleich eigentlich nicht, aber wenn er denn was nützen soll dann sollte der Code auch vergleichbar sein. Mit Codeauszügen ist das schwierig weil es mühseelig ist den speziellen Code der für die Subroutine zuständig ist herauszupicken, zudem greift Bascom auch in Assember sehr schnell auf Subroutinen im Code zurück, so das dies ohnehin schwierig ist. Es wäre viel einfacher und auch aussagekräftiger wenn das komplette Programm auf beidne Seiten als Assembler aufgelistet würde, so wie es Darwin jetzt oben in Bascom gemacht hat. Ansonsten würden Benchmarks für bestimmte Aufgaben (Rechenzeit/Codegröße) für viele sicher interessanter sein.
--Frank 01:12, 24. Apr 2006 (CEST)
Das "Spaghetti-Code" bezog sich auf das Disassemble der hex-Datei, nicht auf die BASIC-Quelle.
Das "While I >= 0" ist immer noch nicht korrekt. Der erste Wert, der addiert wird, ist dann immer noch N-1 und nicht N. Ausserden würde mit >=0 am Ende eine -1 addiert werden, weil das Decr vor der Summe steht.
Ein Codevergleich ist ja so was wie ein Benchmark. Und einfache Routinen, die in den Sprachen gleich aussehen (die Summenberechnung sieht in C ja genauso aus wie in BASIC), sind ja im Artikel als Vorschlag drinne. Irgendw muss man ja anfangen. Laufzeitbestimmungen könnte man natürlich auch machen...
Den Assembler-Code von Darwin sehe ich momentan nicht. Das einzige was ich hab, ist ein HEX-Dump (Maschinen-Code) und ein Assembler-Code aus dem hex. Der Code der Routine kann man schon in etwa zuordnen. Und die kleinen Funktiönchen, die Bascom aufruft, sind wahrscheinlich feste Bausteine, die auch von anderen Funktionen (falls vorhanden) mitverwendet würden.
Das sehe ich nicht so. Ein "Bänschmarg" sollte eigentlich die reíne Rechenleistung wiedergeben. Codeoptimierung ist da was ganz anderes. Zumal ein längerer Code durchaus schneller als ein kompakter Code sein KANN. Manche Befehle benötigen mehr "Ticks" als andere. In Vielen Sprachen ist zwar x=x+1 langsamer und länger als inc x, dies muss aber nicht für alle Befehle gelten und ist ja auch noch kein Compilat, es wird aber auf unterschiedliche Weisen das gleiche Ergebniss erzielt (Das Ziel ist der Weg). Waurm wurde wohl der RISC entwickelt (Reduced InStruction Code). Da muss ma auch mehrere Befehle ausführen als mit einem "NonRISC" System, trozdem sollte das "RISC-System" schneller arbeiten.
--Darwin.nuernberg 23:43, 26. Apr 2006 (CEST)
Hallo
Gibt es jetzt darüber eigentlich schon ein Fazit ? Um wieviel ist C jetzt schneller als Bascom ? --Roberto 07:42, 10. Aug 2006 (CEST)