Feld initialisieren
-
Hi groovemaster,
ja stimmt, hatte in letzter Zeit eher mit Netzwerken zu tun.
In der Sache selbst:
Ich hab' den MSVC selbst nicht, wundere mich aber schon sehr, daß er WIRKLICH ein Array eine Million mal neu anlegen soll. Einerseits ist das völliger Blödsinn, zweitens habe ich keinen Compiler, der sich nicht weigert, das Deklarieren und Initialisieren innerhalb einer Schleife auszuführen.Um das dennoch ausmessen zu können, habe ich das im Frame einer aufgerufenen Funktion erledigen lassen und kam beim M16C so auf die gut 6000 Zyklen.
Messen tue ich das übrigens mit einem Simulator und auch nur für einen Durchlauf, weil uns ja die Parallelisierungs- und Cache- Tricksereien der i386- Familie nicht interessieren sollen. Wir sind ja schließlich im ANSI C- Forum.
Und wenn man die Sourcen vergleicht ...
a) memset aus der strings.h:void *memset( void *s, int c, size_t n ) { char *ss=s; while ( n-- ) *ss++ = ( char )c; return ( (char *)s ); /* */ }
Resultierender Assemblercode:
0F0758 7CF204 $memset ENTER #04H 0F075B 73B009 MOV.W 9H[FB],R0 0F075E 73BB05FC MOV.W 5H[FB],-4H[FB] 0F0762 73BB07FE MOV.W 7H[FB],-2H[FB] 0F0766 7301 MOV.W R0,R1 0F0768 C9F0 ADD.W #-1H,R0 0F076A D101 CMP.W #0H,R1 0F076C 6A17 JEQ F0784H 0F076E 7324 MOV.W R2,A0 0F0770 7242 MOV.B A0,R1L 0F0772 7342 MOV.W A0,R2 0F0774 73B4FC MOV.W -4H[FB],A0 0F0777 73B5FE MOV.W -2H[FB],A1 0F077A 7422 STE.B R1L,[A1A0] 0F077C C91BFC ADD.W #1H,-4H[FB] 0F077F 77EBFE ADCF.W -2H[FB] 0F0782 FEE3 JMP.B F0766H 0F0784 73B005 MOV.W 5H[FB],R0 0F0787 73B207 MOV.W 7H[FB],R2 0F078A 7DF2 EXITD
Der richtigerweise mit sizeof korrigierte Aufruf benötigt übrigens tatsächlich um die 60'000 Zyklen.
b) for- Schleife
for (i = 0; i< 1000; i++) { array[i] = 0; }
resultierender Assemblercode:
0F013A D90BFE MOV.W #0H,-2H[FB] 0F013D 778BFEE803 CMP.W #03E8H,-2H[FB] 0F0142 7DCA0F JGE F0153H 0F0145 73B4FE MOV.W -2H[FB],A0 0F0148 E904 SHL.W #1H,A0 0F014A D90C1004 MOV.W #0H,0410H[A0] 0F014E C91BFE ADD.W #1H,-2H[FB] 0F0151 FEEB JMP.B F013DH
... dürfte klar sein, daß memset mehr zu erledigen hat - oder
?
Am Bild ändert sich auch nicht viel, wenn man die paar Zeilen durch den IAR- Compiler schickt. Bei Keil C für 8051 sieht es ähnlich aus, nur daß der 8051er ein lahmer Hund ist.
Also, es bleibt dabei: Am schnellsten geht es, wenn ein Array beim Deklarieren auch initialisiert wird, dann kommt die Scheife und memset bitte nur nehmen, wenn's nicht anders geht.
-
@net hübscher Versuch Natürlich war gemeint unser "tolles" Array mit 1000 Elementen so möglichst effektiv zu füllen.
@pointercrash() Danke für die Information das du mit einem µController Typ 8051 arbeitest.
Leider ist es so, das solche Implementierung von Routinen sehr stark Architektur und Hersteller abhängig sind.
Wie könnte es sonst sein das der Intel 80x86 oder gnu Compiler immer noch performanter ist als der M$.Also, es bleibt dabei: Am schnellsten geht es, wenn ein Array beim Deklarieren auch initialisiert wird, dann kommt die Scheife und memset bitte nur nehmen, wenn's nicht anders geht.
Diese Aussage ist nur richtig wenn du dich auf deine Architektur bezeihst, Hast du diesilben Versuche mal mit IAR Compiler und Target z80 gemacht?
Und so schlecht ist eine 8051 als 8 Bit Microcontroller nun auch wieder nicht, die Architektur gibts seit vor 1994.
Und obs die "modernen" Pic´s wirklich besser machen?Andere Frage Welchen IAR und welchen Keil Compiler benutzt du, und wie bist du damit zufrieden, Ich tendiere mehr zum IAR-Compiler
-
@pointercrash()
Kannst du mal den Assemblercode vonint a[100] = {};
für deine Plattform posten. Würde mich echt mal interessieren. Zum einen, da ich Nullinitialisierung bisher immer mit
int a[100] = {0};
gemacht habe. Aber so, wie ich den Standard verstehe, dies auch ohne die 0 funktionieren sollte. Zum anderen interssiert mich auch der Vergleich zur Schleife.
pointercrash() schrieb:
Am schnellsten geht es, wenn ein Array beim Deklarieren auch initialisiert wird
Jaja, RAII ist doch 'ne schöne Sache.
-
MSVC meldet sich wie folgt bei
int array[1000] = {};E:\aufl\aufl.cpp(19) : error C2059: Syntaxfehler : '}'
E:\aufl\aufl.cpp(19) : error C2143: Syntaxfehler : Fehlendes ';' vor '}'
E:\aufl\aufl.cpp(19) : error C2143: Syntaxfehler : Fehlendes ';' vor '}'Meiner Ansicht nach ist das eine Unsauberkeit in der Implemtierung von deinem C-Compiler
Beim IARC Compiler 3.0 haben die es auch fertig gebracht toupper nicht mit einem Bitweise Oder zu implementieren sondern
duch abziehen von 0x20 und zwar sowohl beim Z80 als auch beim 8051. Sah toll aus wenn man toupper zweimal nacheinander anwendete. Ist dann auf unseren "Wunsch" ab Version 4 korrigiert worden.
-
Hi groovemaster und Konsorten!
also,
int belegt[1000] = {0};
und
int belegt[1000] = {};
sind codeidentisch. Und wenn man sich das ansieht, wird auch klar, warum der Code so schnell ist:
0F0120 7CF2C8 _belegen ENTER #C8H 0F0123 7BF5 STC FB,A1 0F0125 77554800 SUB.W #0048H,A1 0F0129 7AF5 LDC A1,FB 0F012B D90B80 MOV.W #0H,-80H[FB] 0F012E D90B82 MOV.W #0H,-7EH[FB] 0F0131 D90B84 MOV.W #0H,-7CH[FB] 0F0134 D90B86 MOV.W #0H,-7AH[FB] 0F0137 D90B88 MOV.W #0H,-78H[FB] 0F013A D90B8A MOV.W #0H,-76H[FB] 0F013D D90B8C MOV.W #0H,-74H[FB] 0F0140 D90B8E MOV.W #0H,-72H[FB] 0F0143 D90B90 MOV.W #0H,-70H[FB] ... usw, usw und so fort ...
Da war ich selber platt - Speed zu Lasten Codekompaktheit, aber gleich derb
.
@PAD
Der Assemblercode wurde mit dem NC30 für M16C erzeugt, der IAR für M16C verhält sich bis auf ein paar Taktzyklen Unterschied identisch. Den Gegentest habe ich mit einem Keil C für 8051 älteren Baujahrs gemacht, wobei ich nur 30 Elemente angefordert habe. Aber die Ergebnisse bleiben übertragbar.
Den IAR hab' ich nur als Demoversion, und das wird auch so bleiben - hab' mit denen fast nur schlechte Erfahrungen gemacht, aus ähnlichen Gründen wartet der Keil C seit 1994 auf ein Update
-
pointercrash() schrieb:
0F0120 7CF2C8 _belegen ENTER #C8H 0F0123 7BF5 STC FB,A1 0F0125 77554800 SUB.W #0048H,A1 0F0129 7AF5 LDC A1,FB 0F012B D90B80 MOV.W #0H,-80H[FB] 0F012E D90B82 MOV.W #0H,-7EH[FB] 0F0131 D90B84 MOV.W #0H,-7CH[FB] 0F0134 D90B86 MOV.W #0H,-7AH[FB] 0F0137 D90B88 MOV.W #0H,-78H[FB] 0F013A D90B8A MOV.W #0H,-76H[FB] 0F013D D90B8C MOV.W #0H,-74H[FB] 0F0140 D90B8E MOV.W #0H,-72H[FB] 0F0143 D90B90 MOV.W #0H,-70H[FB] ... usw, usw und so fort ...
ne kleine schleife hätt's aber auch nicht viel langsamer gemacht. ausserdem, wenn man bedenkt dass das array 1000 elemente hat wird der code auch nicht greade klein. und sowas macht ein embedded-compiler tztztz...
-
@pointercrash()
Kannst du mir Mehr Informationen über "NC30 für M16C" liefern. Wir evaluieren gerade in unserer HW-gruppe eine USB2.0 zu PCI BC Bridge die hat einen 8051 Derivat drauf. Zur Zeit wollen wir dafür IAR C8051 Version 4.0 Baujahr 1994 einsetzen, aber wen es etwas besseres gibt.Schon mal vielen Dank.
-
@PAD:
Kommt drauf an, was Du eigentlich machen willst. Wenn Du einen Compiler hast, der tut, behalt' ihn. Wenn's nur um die Bequemlichkeit bei der Entwicklung geht, wäre http://www.keilsoftware.com/c51/ ein Kandidat. Der hat zwar noch immer Macken, aber die IDE ist schön.Die Frage ist, ob das Ding grundlegend neu aufgezogen werden soll und da ist so gut wie alles besser als der 8051 und seine aufgebohrten Derivate.
Die Andeutung klingt nach einer typischen Aufgabe für ein FPGA, z.B. von Altera mit dem NIOS2- Core. Die Hardware packt man in VHDL- Libraries und den Core kann man ganz normal in C programmieren. Wenn der Core nicht gefällt, gibt's weitere Cores, wie z.B. ARM und sogar die alte Krücke 8051, die über eine PLL getuned mit 400 MHz abfetzen kann. Nachteil ist halt, daß die Evaluation tools für ein Butterbrot verschmissen werden, die Productivity tools aber immer noch richtig Geld kosten.
Wenn Du mehr wissen magst, mußt halt nachfragen - aber besser nimmer in diesem Forum.
-
@pointercrash() Missverständnis: Dieser Baustein ist ein Kaufteil, dessen Programmierung wir für unsere Zwecke adaptiern müssen. Ich kenne Keil mag ihn aber nicht, Benutze erfolgreich für die Wartung von bestehenden Projekten IARC 4.0 von ca 1994
Das Projekt soll eine Diplomarbeit werden Dabei könnte man auch einen neuen Compiler ?"NC30 für M16C"? ausprobiern.Bei der FPGA und ASIC entwicklugn setzen wir derzeit auf ARM7. Für einige neue Projekte bei denen die Rechenleistung nicht mehr reicht, bzw der Strom Verbrauch zu hoch ist untersuchen wir gerade den BlackFin in der Hoffnung drei ASIC´s mit ARM durch einen Blackfin mit einem FPGA später ASIC zu ersetzen
-
@PAD
Achso, dann liegt da wohl noch ein weiteres Mißverständnis vor: Der NC30 erzeugt Objectfiles ausschließlich für den M16C Prozessor. Ich habe nur zum Gegentest die gleiche Source durch mein Keil C für 8051 geschossen und mit PSIM51 die Takte zählen lassen.Mit 8051 mache ich auch schon lang nichts mehr außer Produktpflege von uralt- Sachen.
Wenn's Dir mit 8051 aber ernst ist, schau' Dir mal das hier an: http://www.tasking.com/products/8_16_bit/8051/
Der Compiler für M16C von Tasking hat mir eigentlich besser gefallen als der NC30, aber der war halt die entscheidenden Euros teurer. Ob sich das auf den 8051 übertragen läßt, weiß ich nicht, aber lad' doch mal die Demo.