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 von

    int 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.


Anmelden zum Antworten