Forum: FPGA, VHDL & Co. Microblaze Performance


von ChrisB (Gast)


Lesenswert?

Hallo,

ich habe ein Spartan3 (XC3S4000FGG676-5C) FPGA Modul mit 48 MHz Quarz. 
Um einmal zu testen, welche Performance der Microblaze (v7.10d) auf 
diesem System hat habe ich ein paar Versuche getätigt.
Der Microblaze läuft mit einer Frequenz von 80 MHz, die aus den 48MHz 
des Quarzes durch den DCM generiert werden. Dem Microblaze habe ich so 
ziemlich alles mitgegeben was geht, FPU, Integer Multiplier, Integer 
Divider, Barrel Shifter sowie jeweils 2KB Cache auf der Daten und 
Befehlsseite und 5 Stage Pipeline. Das Programm für die Tests wird von 
einem Bootloader ins externe SDRam geladen und dort gestartet.
Um eine Zeitmessung durchzuführen verwende ich den XPS_Timer. Dieser 
lüuft mit den vollen 80MHz Systemtakt. Wenn ich den Timerwert zweimal 
hintereinander auslese, so erhalte ich einen Wert von 125, was ich 
zunächst einmal als Offset-Takte ansehe. Zwischen beide 
Timerauslese-Vorgänge mache ich nun verschiedene Operationen und erhalte 
die Taktzahl des Befehls (den Offset habe ich abgezogen).
Folgende Werte sind dabei herausgekommen:
Zuweisung "i=1;"       92 Takte
SDRam 32Bit schreiben  127 Takte
SDRam 32Bit lesen      99 Takte
Float multiplizieren   28795 Takte
Float dividieren       18091 Takte

Diese paar Werte sollen erstmal reichen.
Was mir direkt aufgefallen war ist, dass die Werte allgemein doch sehr 
hoch sind. Wie kommen diese hohen Werte zustande? Vor allem bei den 
Float-Multiplikation gibt Xilinx an, dass diese in 4 takten, die 
Division in 28 Takten zu schaffen sei. Da bin ich aber doch sehr weit 
entfernt, obwohl der Haken bei FPU in den Microblaze Einstellungen 
vorhanden ist.
Aber auch das Lesen und Schreiben vom SDRam müsste doch in 10 Takten zu 
schaffen sein oder etwa nicht? Mache ich bei der Auswertung etwas 
falsch? Bei der Opitimiereng die der Compiler vornehmen kann habe ich 
alle Einstellungen ausprobiert, jedoch ohne großartige Änderungen.
Vielleicht hat ja von euch jemand eine Idee, was hier schief geht...
Gruß, Christoph

von Duke Scarring (Gast)


Lesenswert?

Bei mir dauert das "normale" Lesen von einem BRAM auch schon 10 Takte. 
Die Stärke des Microblaze scheint damit nicht so sehr in der 
IO-Performance zu liegen.

Duke

von DI UV (Gast)


Lesenswert?

SDRAM ist nicht ganz einfach im Zugriff (Bank schliessen, neue öffnen, 
prefetch,...) , da kann der erste Zugriff schon ne weile dauern. 
Realistischer (zumal du ja extra cache in deinem System hast) ist das 
das lesen von 16 Daten am Blöck.

Einige Busse am uB sind mit waitstates konfiguriert, vielleicht liegt es 
daran.


i=1 in 10 Takten mag ich wirklich glauben (ist i im Register?).

Sind vielleicht die datentypen zu groß (64 bit) und es sind in echt 
mehrere Zugriffe nötig (da 32 bit system oder 16 bit bus). Schau dir mal 
die Datenbreite des Busses an.

MfG,

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Laß das Programm vorallem mal vom internem Ram aus laufen...
und ggf mal das ASM listing betrachten.
Ich würde auch Stack und Heap erstmal in den internen Ram verfrachten.

von DI UV (Gast)


Lesenswert?

Korrektur:

> i=1 in 10 Takten mag ich wirklich glauben (ist i im Register?).

hab mich vertippt, soll heissen:

 i=1 in 10 Takten mag ich wirklich NICHT glauben (ist i im Register?).

von ChrisB (Gast)


Lesenswert?

Soo hab jetzt alles mal ins BRam gemacht, dort gehts deutlich schneller.
Hier mal mein Ergebnis fürs SDRam (Die Zahl hinter diff gibt die Anzahl 
der Takte an):

Offset: start: 3694914, end: 3694789,       diff: 125
SDRam schreiben ( 8Bit): start: 3307401, end: 3307180,   diff: 96
SDRam lesen ( 8Bit): start: 2852301, end: 2852079,   diff: 97
SDRam schreiben (16Bit): start: 2420327, end: 2420106,   diff: 96
SDRam lesen (16Bit): start: 1962411, end: 1962189,   diff: 97
SDRam schreiben (32Bit): start: 1533853, end: 1533601,   diff: 127
SDRam lesen (32Bit): start: 1066168, end: 1065946,   diff: 97
Zuweisung: start: 666999, end: 666812,       diff: 62
U08 add: start: 324233, end: 323885,       diff: 223
U08 sub: start: 7989981, end: 7989633,       diff: 223
U08 mul: start: 7615069, end: 7613636,       diff: 1308
U08 div: start: 7236778, end: 7230341,       diff: 6312
U16 add: start: 6864495, end: 6864054,       diff: 316
U16 sub: start: 6512587, end: 6512146,       diff: 316
U16 mul: start: 6150292, end: 6148549,       diff: 1618
U16 div: start: 5774912, end: 5767974,       diff: 6813
U32 add: start: 5404223, end: 5403968,       diff: 130
U32 sub: start: 5053976, end: 5053721,       diff: 130
U32 mul: start: 4693431, end: 4691564,       diff: 1742
U32 div: start: 4318054, end: 4310547,       diff: 7382
U64 add: start: 3949057, end: 3948672,       diff: 260
U64 sub: start: 3601188, end: 3600803,       diff: 260
U64 mul: start: 3243774, end: 3232991,       diff: 10658
U64 div: start: 2866074, end: 2827091,       diff: 38858
F32 add: start: 2482778, end: 2470956,       diff: 11697
F32 sub: start: 2117319, end: 2105056,       diff: 12138
F32 mul: start: 1748761, end: 1719849,       diff: 28787
F32 div: start: 1379891, end: 1361684,       diff: 18082
F64 add: start: 1016372, end: 997991,       diff: 18256
F64 sub: start: 676799, end: 655104,       diff: 21570
F64 mul: start: 329401, end: 233341,       diff: 95935
F64 div: start: 7944629, end: 7825620,       diff: 118884

Und jetzt das gleiche, wenn das Programm im BRam läuft:

Offset: start: 7999922, end: 7999908,       diff: 14
SDRam schreiben ( 8Bit): start: 7766009, end: 7765980,   diff: 15
SDRam lesen ( 8Bit): start: 7318828, end: 7318777,   diff: 37
SDRam schreiben (16Bit): start: 6899140, end: 6899111,   diff: 15
SDRam lesen (16Bit): start: 6451944, end: 6451893,   diff: 37
SDRam schreiben (32Bit): start: 6032258, end: 6032229,   diff: 15
SDRam lesen (32Bit): start: 5585066, end: 5585015,   diff: 37
Zuweisung: start: 5165382, end: 5165366,     diff: 2
U08 add: start: 4821387, end: 4821362,       diff: 11
U08 sub: start: 4484256, end: 4484231,       diff: 11
U08 mul: start: 4147140, end: 4147077,       diff: 49
U08 div: start: 3810016, end: 3809784,       diff: 218
U16 add: start: 3466022, end: 3465996,       diff: 12
U16 sub: start: 3128909, end: 3128883,       diff: 12
U16 mul: start: 2791785, end: 2791714,       diff: 57
U16 div: start: 2454659, end: 2454410,       diff: 235
U32 add: start: 2110656, end: 2110636,       diff: 6
U32 sub: start: 1780422, end: 1780402,       diff: 6
U32 mul: start: 1450177, end: 1450101,       diff: 62
U32 div: start: 1113058, end: 1112784,       diff: 260
U64 add: start: 3369839, end: 3369815,       diff: 10
U64 sub: start: 3032705, end: 3032681,       diff: 10
U64 mul: start: 2695590, end: 2695222,       diff: 354
U64 div: start: 2351597, end: 2350234,       diff: 1349
F32 add: start: 7766136, end: 7765731,       diff: 391
F32 sub: start: 7408384, end: 7407962,       diff: 408
F32 mul: start: 7050615, end: 7049619,       diff: 982
F32 div: start: 6692855, end: 6692249,       diff: 592

Man sieht deutlich, dass es ca. um Faktor 8 schneller ist.
Aber es drei Sachen verstehe ich nicht:
1. Warum brauchen float Operationen so lange, obwohl ich die FPU 
aktiviert habe?
2. Was ist der Grund dafür, dass das Programm im SDRam so stark 
langsamer ist? Klar wird es etwas langsamer sein, aber so einen großen 
Unterschied hätte ich nicht erwartet.
3. Kann es sein, dass etwas mit den Cache Einstellungen nicht stimmt, so 
dass der MB den Cache nur fürs BRam verwendet und fürs SDRam garnicht? 
Oder lässt sich durch Einstellungen des Memory Controllers noch 
Performance rausholen?

Gruß,
Christoph

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Wie gesagt... schau dir das ASM Listing an... ich glaub eher das der MB 
viel mehr "machen" muß, als du denkst, gerade aufgrund deiner 
"Benchmarks".

Und bzgl des SRAMs zitier ich mal das MB Datenblatt:
>When executing from slower memory, instruction fetches may
>take multiple cycles. This additional latency directly
>affects the efficiency of the pipeline.

Zwar hat der MB nen prefetch buffer, aber dieser muß bei jedem genommen 
Sprung neu aufgebaut werden!

>The MicroBlaze instruction and data caches can be configured
>to use 4 or 8 word cache lines. When using a longer cache line,
>more bytes are prefetched, which generally improves performance
>for software with sequential *access* patterns.
>However, for software with a more random *access* pattern the
>performance can instead _decrease_
>for a given cache size. This is caused by a reduced cache hit rate
>due to fewer available cache lines.

Float Operationen können so lange dauern weil diese das ausführen 
Nachfolgender Befehle verzögern, oder der compiler nicht die HW FP 
Operationen verwendet, deshalp --> Listing ansehen

von ChrisB (Gast)


Lesenswert?

Okay, werde mir das ASM Listing mal anschauen, aber wo genau finde ich 
das?
Bisher habe ich nur eine *.elf, eine *.o und eine *.d Datei gesehen, 
aber dort befindet sich so wie ich das sehe kein ASM Code. Oder muss ich 
mir den ASM Code selbst erzeugen, bzw. durch Optionen selber erzeugen 
lassen?

von DI UV (Gast)


Lesenswert?

<Oder muss ich
<mir den ASM Code selbst erzeugen, bzw. durch Optionen selber erzeugen
<lassen?

Früher hat man dem gcc die Option -s mitgegegeben, damit er den 
Assembler-Quellcode ausgibt.

MfG,

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Rechtsklick auf das Projekt --> Set compile Options --> Path and Options
dort bei Other Compiler Options -save-temps eintragen. dann behaält er 
das erzeugte (.s) file. 
(http://www.delorie.com/djgpp/v2faq/faq8_20.html)

von ChrisB (Gast)


Lesenswert?

Ich habe auch gerade mal den Cache ausgeschaltet -> keine Veränderung 
bei den Takten, ist alles beim Alten geblieben, das kann eigentlich 
nicht sein oder?

@Läubi:
Bezüglich deines letzten Posts,
Ist denn der externe SDRam wirklich so viel langsamer, so, dass der 
Microblaze so starke Unterschiede zum internen BRam zeigt? Als externen 
SDRam verwende ich den " http://www.issi.com/pdf/42S32160A.pdf " So 
langsam erscheint der mir eigentlich garnicht.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Naja sagen wir mal der braucht 5 Takte für einen Lesezugriff, dann 
dauern alle Befehle (im mittel) 5 takte länger...
Stell doch sonst mal das listing file rein.

von DI UV (Gast)


Lesenswert?

< Ist denn der externe SDRam wirklich so viel langsamer

Ja SDRAM ist nicht SRAM, vor dem READ muss 3 takte vorher ein AVTIVATE 
passieren, und nach dem READ dauert es noch die CAS-Latency biss die 
Daten anliegen. Dann muss man meist noch in die verschiedenen 
taktdomainen einsynchronisieren. DER SDRAM ist nicht unbedingt 
langsamer, er hat nur eine lange "Anfahrzeit" (Latenz). Deshalb sollte 
man Block und keine Einzeltransfer messen um die Durchsatzrate zu 
bestimmen. Oder mehrmals laufen lassen.

MfG

von ChrisB (Gast)


Lesenswert?

Okay, ich kann ja mal einfach 1KByte ins SDRam schreiben bzw. 1KByte aus 
dem SDRam lesen und dort die Zeit messen, mal sehen wie die sich im 
bezug auf einen einfachen ransfer verhält...

von ChrisB (Gast)


Lesenswert?

Um der ganzen Sache nach und nach auf den Grund zu gehen analysiere ich 
gerade den generierten ASM-Code
Mir ist aufgefallen, dass er aus dem

C-Code: i=1;

den ASM Code:
addik  r3,r0,1  # 0x1
swi  r3,r19,36

macht.
Somit initialisiert er nicht nur ein Register mit 1, sondern speichert 
dieses auch gleich im SDRam ab, wenn ich das richtig interpretiere. Aus 
welchem Grund wird das im SDRam gespeichert? Ich verwende diese Variable 
i im ganzen Progrmam nicht mehr.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Wenn die data area im SDRam liegt wird er das auch dort hinspeichern...
Leg mal Stack und Heap in den Bram.. könnte aber auch sein das du ggf ne 
andere Optimierungsstufe einstellen mußt.

von ChrisB (Gast)


Lesenswert?

Heap und Stack im Bram wird glaube nicht so einfach glaube ich, oder 
kann man einfach angeben, wo sich das befinden soll? Starte mein 
Progeramm ja mit nem Bootloader...

von ChrisB (Gast)


Lesenswert?

Weiss sowieso im Moment nicht genau was ich machen soll. Im BRAm hab ich 
momentan meinen Bootloader. Deswegen habe ich das normale Programm im 
SDRam. Jetzt merk ich, dass es dort doch sehr langsam zu sein scheint, 
jedoch ist das BRAM eigentlich zu klein für mein Programm (also wenn es 
fertig ist). Ich kann es so wie ich das gesehen habe bis 64KB 
einstellen. Das ist shcon etwas arg wenig. Was für eine Möglichkeit habe 
ich noch? Hat jemand eine Idee?

von ChrisB (Gast)


Lesenswert?

Ich hab hier gerade etwas im Netz gefunden: 
http://www1.cs.columbia.edu/~soviani/cs4840hack/Microblaze_timing.html
Die müssen irgendwas anders amchen als ich...

von Zukunftsspäher (Gast)


Lesenswert?

Interessant, hat mir doch ein Kolleche erzählt das es in neueren 
EDK-Versionen einen Ersatz für den OPB-Bus gibt. Unter dem dir genannten 
steht für Zugriffe über den (neuen) LMB 1 Takt, für den (alten) OPB bis 
zu 7 Takte. Vielleicht solltest du dein syste neuzusammenklickern und 
dabei auf den LMB achten ?! Kann man die FPU auch an den LMB (statt OPB) 
klemmen?

von ChrisB (Gast)


Lesenswert?

Also der Bram ist am LMB, der SDRam Controller ist am OPB. An welchem 
Bus jetzt die FPU hängt kann ich dir nicht sagen, aber ich nehme an dass 
die garnicht extern am Microblaze hängt, sondern intern verdrahtet 
ist...
Was genau soll ich versuchen an den LMB zu hängen? den SDRam Controller? 
Ich glaube das ist garnicht möglich, aber werde mal gucken ob es geht.

von ChrisB (Gast)


Lesenswert?

Ich habe jetzt noch einmal etwas mit dem System rumgespielt. Es sieht 
tatsächlich so aus, als wäre der Cache fürs SDRam nicht eingeschaltet. 
Wollte diesen jetzt einschalten, jedoch kann ich den Microblaze dann 
nicht mehr mit 80 MHz betreiben. Woran kann das liegen? Kann man dies 
umgehen?

von ChrisB (Gast)


Lesenswert?

Ich habe jetzt nochmal wegen der FPU geguckt. Also eingeschaltet ist 
diese, der Compiler macht mir aus der float-Multiplikation folgenden ASM 
Code:
lwi  r5,r19,44
lwi  r6,r19,40
brlid  r15,__mulsf3 ## Need to verify this
nop    # Unfilled delay slot
swi  r3,r19,36
Ist dieser ASM-Code nun so, dass die FPU angesprochen wird, oder wird 
die float-Zahl auf üblichem Weg ohne FPU ausgerechnet?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

er ruft die Unterfunktion __mulsf3 auf...

Ich hätte jezt eher sowas erwartet:
1
lwi  r5,r19,44
2
lwi  r6,r19,40
3
fmul r3, r5, r6
4
swi  r3,r19,36
Spart Platz und Ausführungszeit... sieht für mich eher so aus als ob er 
entweder die FPU nicht nuzt, oder der Linker dies (je nach vorhandener 
Hardware) dann umsezt.

Kompilier mal die Debuginfos rein und dann mit objdump von der Binary 
das listfile zu erzeugen.

von ChrisB (Gast)


Lesenswert?

Kenne mich damit leider nicht so gut aus. Wie kann ich die Debug-Infos 
mit reincompillieren und wie genau erzeuge ich dann mit objdump das 
Listfile aus der Binary?
Sorry, habe sowas noch nie gemacht...

Für mich siehts auch so aus, als würde er die FPU garnicht nutzen, 
genauso wie das Cache. Es macht nämlich momentan keinen Unterschied, ob 
ich den Cache einschalte oder auslasse. Das wundert mich sehr. Kann es 
sein, dass das Xilinx SDK irgendwie nicht mitbekommt, welche Features 
beim Microblaze aktiv und welche deaktiv sind?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Also ggf mut du mal das Bitfile + die Softwarelibs neu bauen.

Die Debuginfos kannst du im Compilersettings Dialog aktivieren, objdum 
gehört zum gcc --> http://www.linuxjournal.com/article/7269 ziemlich am 
Ende ist der aufruf von objdump beschrieben: objdump -d test.o

von ChrisB (Gast)


Lesenswert?

Also selbst wenn ich das Bitfile, die Softwarelibs und mein Programm 
cleane und neu baue gibt es keine Änderung bei der Anzahl der Takte. 
Müsste denn irgendwo im SDK sichtbar sein, ob Cache oder die FPU 
aktiviert sind? Lässt sich dies irgendwo erkennen?

Ich probiere jetzt mal das mit dem objdump

von ChrisB (Gast)


Lesenswert?

Also habe mir jetzt ein Programm geschirbeen, dass einfach nur zwei 
floats multipliziert:
int main (void)
{
  U32 x1=123.45,x2=567.89,x3=0.0;
  x3=x1*x2;
  return (int)x3;
}
wenn ich jetzt objdump -d app.o in der Konsole eingebe, erhalte ich 
folgendes:
00000000 <main>:
   0:   3021ffd4        addik   r1, r1, -44
   4:   f9e10000        swi     r15, r1, 0
   8:   fa610028        swi     r19, r1, 40
   c:   12610000        addk    r19, r1, r0
  10:   3060007b        addik   r3, r0, 123
  14:   f8730024        swi     r3, r19, 36
  18:   30600237        addik   r3, r0, 567
  1c:   f8730020        swi     r3, r19, 32
  20:   f813001c        swi     r0, r19, 28
  24:   e8b30024        lwi     r5, r19, 36
  28:   e8d30020        lwi     r6, r19, 32
  2c:   b0000000        imm     0
  30:   b9f40000        brlid   r15, 0
  34:   80000000        or      r0, r0, r0
  38:   f873001c        swi     r3, r19, 28
  3c:   e873001c        lwi     r3, r19, 28
  40:   e9e10000        lwi     r15, r1, 0
  44:   10330000        addk    r1, r19, r0
  48:   ea610028        lwi     r19, r1, 40
  4c:   3021002c        addik   r1, r1, 44
  50:   b60f0008        rtsd    r15, 8
  54:   80000000        or      r0, r0, r0

So wie ich das überschauen kann sehe ich da garnichts von einer 
Multiplikation oder? Theoreitsch sollte ja jetzt irgendwo FMUL 
auftauchen.

von ChrisB (Gast)


Lesenswert?

Ohh sorry, hab ausversehn U32 Variablen erstellt, sollte F32 sein, also 
nochmal:
C-Code:
int main (void)
{
  F32 x1=123.45,x2=567.89,x3=0.0;
  x3=x1*x2;
  return (int)x3;
}

ASM-Code:
  lwi  r5,r19,36
  lwi  r6,r19,32
  brlid  r15,__mulsf3 ## Need to verify this
  nop    # Unfilled delay slot

  swi  r3,r19,28

Und die Ausgabe des objdump -d app.o :

app.o:     file format elf32-microblaze

Disassembly of section .text:

00000000 <main>:
   0:   3021ffd4        addik   r1, r1, -44
   4:   f9e10000        swi     r15, r1, 0
   8:   fa610028        swi     r19, r1, 40
   c:   12610000        addk    r19, r1, r0
  10:   b00042f6        imm     17142
  14:   3060e666        addik   r3, r0, -6554
  18:   f8730024        swi     r3, r19, 36
  1c:   b000440d        imm     17421
  20:   3060f8f6        addik   r3, r0, -1802
  24:   f8730020        swi     r3, r19, 32
  28:   10600000        addk    r3, r0, r0
  2c:   f873001c        swi     r3, r19, 28
  30:   e8b30024        lwi     r5, r19, 36
  34:   e8d30020        lwi     r6, r19, 32
  38:   b0000000        imm     0
  3c:   b9f40000        brlid   r15, 0
  40:   80000000        or      r0, r0, r0
  44:   f873001c        swi     r3, r19, 28
  48:   e8b3001c        lwi     r5, r19, 28
  4c:   b0000000        imm     0
  50:   b9f40000        brlid   r15, 0
  54:   80000000        or      r0, r0, r0
  58:   e9e10000        lwi     r15, r1, 0
  5c:   10330000        addk    r1, r19, r0
  60:   ea610028        lwi     r19, r1, 40
  64:   3021002c        addik   r1, r1, 44
  68:   b60f0008        rtsd    r15, 8
  6c:   80000000        or      r0, r0, r0

Trotzdem keine Multiplikation oder?

von ChrisB (Gast)


Lesenswert?

Habe gerade gesehen mit objdump -D app.o Disassembliert er alles.
So erhalte ich:


app.o:     file format elf32-microblaze

Disassembly of section .text:

00000000 <main>:
   0:   3021ffd4        addik   r1, r1, -44
   4:   f9e10000        swi     r15, r1, 0
   8:   fa610028        swi     r19, r1, 40
   c:   12610000        addk    r19, r1, r0
  10:   b00042f6        imm     17142
  14:   3060e666        addik   r3, r0, -6554
  18:   f8730024        swi     r3, r19, 36
  1c:   b000440d        imm     17421
  20:   3060f8f6        addik   r3, r0, -1802
  24:   f8730020        swi     r3, r19, 32
  28:   10600000        addk    r3, r0, r0
  2c:   f873001c        swi     r3, r19, 28
  30:   e8b30024        lwi     r5, r19, 36
  34:   e8d30020        lwi     r6, r19, 32
  38:   b0000000        imm     0
  3c:   b9f40000        brlid   r15, 0
  40:   80000000        or      r0, r0, r0
  44:   f873001c        swi     r3, r19, 28
  48:   e8b3001c        lwi     r5, r19, 28
  4c:   b0000000        imm     0
  50:   b9f40000        brlid   r15, 0
  54:   80000000        or      r0, r0, r0
  58:   e9e10000        lwi     r15, r1, 0
  5c:   10330000        addk    r1, r19, r0
  60:   ea610028        lwi     r19, r1, 40
  64:   3021002c        addik   r1, r1, 44
  68:   b60f0008        rtsd    r15, 8
  6c:   80000000        or      r0, r0, r0
Disassembly of section .debug_abbrev:

00000000 <.debug_abbrev>:
   0:   01110110                r8, r17, r0
   4:   06120111        neg     r16, r18
   8:   01250813                r9, r5, r1
   c:   0b03081b                r24, r3, r1
  10:   08000002                r0, r0, r0
  14:   24000308        rsubi   r0, r0, 776
  18:   0b0b3e0b                r24, r11, r7
  1c:   00000324                r0, r0, r0
  20:   00030e0b                r0, r3, r1
  24:   0b3e0b00                r25, r30, r1
  28:   00041600                r0, r4, r2
  2c:   03083a0b                r24, r8, r7
  30:   3b0b4913        addikc  r24, r11, 18707
  34:   0000052e                r0, r0, r0
  38:   0101133f                r8, r1, r2
  3c:   0c03083a                r0, r3, r1
  40:   0b3b0b27                r25, r27, r1
  44:   0c491311                r2, r9, r2
  48:   01120140                r8, r18, r0
  4c:   06000006        neg     r16, r0
  50:   34000308        rsubik  r0, r0, 776
  54:   3a0b3b0b        addikc  r16, r11, 15115
  58:   4913020a                r8, r19, r0
  5c:   Address 0x0000005c is out of bounds.

Disassembly of section .debug_info:

00000000 <.debug_info>:
   0:   0000018a                r0, r0, r0
   4:   00020000        add     r0, r2, r0
   8:   00000401                r0, r0, r0
   c:   Disassembly of section .debug_line:

00000000 <.debug_line>:
   0:   0000009c                r0, r0, r0
   4:   00020000        add     r0, r2, r0
   8:   00620101                r3, r2, r0
   c:   f6f50a00        shi     r23, r21, 2560
  10:   01010101                r8, r1, r0
  14:   00000001                r0, r0, r0
  18:   2e2e0000        rsubic  r17, r14, 0
  1c:   74797065                r3, r25, r14
  20:   732e6800                r25, r14, r13
  24:   01000069                r8, r0, r0
  28:   6e74632e        ncget   r19, rfsl14
  2c:   68000100                r0, r0, r0
  30:   0074696d                r3, r20, r13
  34:   65722e68                r11, r18, r5
  38:   00010000        add     r0, r1, r0
  3c:   6770696f        bsrli   r27, r16, 15
  40:   2e680001        rsubic  r19, r8, 1
  44:   00007370                r0, r0, r14
  48:   692e6800                r9, r14, r13
  4c:   01000075                r8, r0, r0
  50:   6172742e        muli    r11, r18, 29742
  54:   68000100                r0, r0, r0
  58:   00693263                r3, r9, r6
  5c:   2e680001        rsubic  r19, r8, 1
  60:   00006170                r0, r0, r12
  64:   702e6300                r1, r14, r12
  68:   01000000        add     r8, r0, r0
  6c:   00050200                r0, r5, r0
  70:   00000004                r0, r0, r0
  74:   083b0005                r1, r27, r0
  78:   02000000        add     r16, r0, r0
  7c:   10150005                r0, r21, r0
  80:   02000000        add     r16, r0, r0
  84:   30150005        addik   r0, r21, 5
  88:   02000000        add     r16, r0, r0
  8c:   48270005                r1, r7, r0
  90:   02000000        add     r16, r0, r0
  94:   58150005                r0, r21, r0
  98:   02000000        add     r16, r0, r0
  9c:   70000101                r0, r0, r0
Disassembly of section .debug_frame:

00000000 <.debug_frame>:
   0:   0000000c                r0, r0, r0
   4:   ffffffff                r31, r31, r31
   8:   0100017c                r8, r0, r0
   c:   0f0c0100                r24, r12, r0
  10:   00000018                r0, r0, r0
        ...
  1c:   00000070                r0, r0, r0
  20:   440e2c48        bsll    r0, r14, r5
  24:   93018f0b                r24, r1, r17
  28:   440d1300        bsra    r0, r13, r2
Disassembly of section .debug_loc:

00000000 <.debug_loc>:
   0:   Disassembly of section .debug_pubnames:

00000000 <.debug_pubnames>:
   0:   00000017                r0, r0, r0
   4:   00020000        add     r0, r2, r0
   8:   Disassembly of section .debug_aranges:

00000000 <.debug_aranges>:
   0:   0000001c                r0, r0, r0
   4:   00020000        add     r0, r2, r0
   8:   00000400                r0, r0, r0
        ...
  14:   00000070                r0, r0, r0
        ...
Disassembly of section .debug_str:

00000000 <.debug_str>:
   0:   6c6f6e67        necaget r3, rfsl7
   4:   20756e73        addi    r3, r21, 28275
   8:   69676e65                r11, r7, r13
   c:   6420696e        bsrli   r1, r0, 14
  10:   Address 0x00000010 is out of bounds.


Hier finde ich wenigstens muli. Was genau ich mit den verschiedenen 
Sektionen anfangen soll weiss ich leider nicht. Und warum er muli macht 
und nicht fmul ist mir auch völlig unklar. Vielleicht weisst du da mehr?

von ChrisB (Gast)


Lesenswert?

Alo das mit dem Cache hab ich jetzt hinbekommen, der war aus irgendeinem 
Grund nicht aktiv. Es lag entweder daran, dass der externe SDRam neben 
dem Cach Link auch über den OPB mit dem Microblaze verbunden war oder 
dass der Cache im Bootloader vor dem Starten der eigentlichen 
Application deaktiviert wurde und erst im Programm wieder aktiviert 
wurde. Jetzt hab ich das so geändert, dass der Cache nach dem Aktivieren 
im Bootloader garnicht mehr deaktiviert wird, funzt jetzt wunderbar. 
Siehe folgende Tabelle:

Offset: start: 4999528, end: 4999513, diff: 15
SDRam schreiben ( 8Bit): start: 4784092, end: 4784058, diff: 19
SDRam lesen ( 8Bit): start: 4503296, end: 4503253, diff: 28
SDRam schreiben (16Bit): start: 4239792, end: 4239757, diff: 20
SDRam lesen (16Bit): start: 3958992, end: 3958944, diff: 33
SDRam schreiben (32Bit): start: 3695472, end: 3695438, diff: 19
SDRam lesen (32Bit): start: 3414672, end: 3414626, diff: 31
Zuweisung: start: 3151146, end: 3151124, diff: 7
U08 add: start: 2935143, end: 2935103, diff: 25
U08 sub: start: 2723464, end: 2723419, diff: 30
U08 mul: start: 2511766, end: 2511725, diff: 26
U08 div: start: 2300109, end: 2300033, diff: 61
U16 add: start: 2088426, end: 2088379, diff: 32
U16 sub: start: 1876745, end: 1876699, diff: 31
U16 mul: start: 1665074, end: 1665016, diff: 43
U16 div: start: 1453372, end: 1453295, diff: 62
U32 add: start: 1241710, end: 1241683, diff: 12
U32 sub: start: 1030012, end: 1029985, diff: 12
U32 mul: start: 818339, end: 818310, diff: 14
U32 div: start: 615286, end: 615224, diff: 47
U64 add: start: 412249, end: 412203, diff: 31
U64 sub: start: 209222, end: 209180, diff: 27
U64 mul: start: 6183, end: 6112, diff: 56
U64 div: start: 4820419, end: 4819160, diff: 1244
F32 add: start: 4600115, end: 4599307, diff: 793
F32 sub: start: 4384102, end: 4383622, diff: 465
F32 mul: start: 4168096, end: 4167600, diff: 481
F32 div: start: 3952109, end: 3951432, diff: 662
F64 add: start: 3736102, end: 3734842, diff: 1245
F64 sub: start: 3515769, end: 3515123, diff: 631
F64 mul: start: 3299784, end: 3298865, diff: 904
F64 div: start: 3083787, end: 3081715, diff: 2057

Das sieht shcon um eineiges besser aus als vorher, damit kann man auch 
schon fast leben denk ich.
Das einzige Problem was ich jetzt noch habe ist die FPU. Diese scheint 
immernoch deaktiv sein und ich vermute es liegt am Compiler. Ich muss 
dies wohl erst irgendwie in den Compiler-Options aktivieren, nur wie?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?


von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Habs gerade mal provbiert, mit der Option macht er die HW mul/add.

ABER!!:
1
F32 x1=123.45,x2=567.89,x3=0.0;
2
  x3=x1*x2;
3
  return (int)x3;
Wird er (berechtigterweise) als konstanten Ausdruck auswerten!

daher:
1
volatile F32 x1, x2, x3;
2
int main (void)
3
{
4
  x1=123.45;
5
  x2=567.89;
6
  x3=x1*x2;
7
  return (int)x3;
8
}

wird bei mir zu:
1
main:
2
  addik  r3,r0,0x42f6e666
3
  addik  r4,r0,0x440df8f6
4
  addik  r1,r1,-28
5
  swi  r3,r0,x1
6
  swi  r4,r0,x2
7
  lwi  r3,r0,x1
8
  lwi  r4,r0,x2
9
  swi  r15,r1,0
10
  fmul  r3,r3,r4
11
  swi  r3,r0,x3
12
  lwi  r5,r0,x3
13
  brlid  r15,__fixsfsi
14
  nop    # Unfilled delay slot
15
16
  lwi  r15,r1,0
17
  rtsd  r15,8 
18
  
19
  addik  r1,r1,28
20
21
  .end  main

von ChrisB (Gast)


Lesenswert?

Genau den Link (http://www.xilinx.com/support/answers/31770.htm) hab ich 
auch gerade gefunden, jetzt funzt es...

Aktuelle Werte:

Offset: start: 4999540, end: 4999525, diff: 15
SDRam schreiben ( 8Bit): start: 4784076, end: 4784042, diff: 19
SDRam lesen ( 8Bit): start: 4503281, end: 4503238, diff: 28
SDRam schreiben (16Bit): start: 4239779, end: 4239744, diff: 20
SDRam lesen (16Bit): start: 3958967, end: 3958919, diff: 33
SDRam schreiben (32Bit): start: 3695438, end: 3695404, diff: 19
SDRam lesen (32Bit): start: 3414638, end: 3414592, diff: 31
Zuweisung: start: 3151124, end: 3151102, diff: 7
U08 add: start: 2935136, end: 2935096, diff: 25
U08 sub: start: 2723454, end: 2723405, diff: 34
U08 mul: start: 2511759, end: 2511716, diff: 28
U08 div: start: 2300100, end: 2300024, diff: 61
U16 add: start: 2088420, end: 2088373, diff: 32
U16 sub: start: 1876745, end: 1876699, diff: 31
U16 mul: start: 1665060, end: 1665002, diff: 43
U16 div: start: 1453364, end: 1453287, diff: 62
U32 add: start: 1241706, end: 1241679, diff: 12
U32 sub: start: 1030026, end: 1029999, diff: 12
U32 mul: start: 818334, end: 818305, diff: 14
U32 div: start: 615304, end: 615242, diff: 47
U64 add: start: 412261, end: 412215, diff: 31
U64 sub: start: 209217, end: 209175, diff: 27
U64 mul: start: 6178, end: 6107, diff: 56
U64 div: start: 4820387, end: 4819029, diff: 1343
F32 add: start: 4600088, end: 4600050, diff: 23
F32 sub: start: 4388401, end: 4388363, diff: 23
F32 mul: start: 4176730, end: 4176692, diff: 23
F32 div: start: 3965045, end: 3964994, diff: 36
F64 add: start: 3753370, end: 3752155, diff: 1200
F64 sub: start: 3533039, end: 3532359, diff: 665
F64 mul: start: 3317044, end: 3313812, diff: 3217
F64 div: start: 3096724, end: 3094759, diff: 1950

Das sieht doch schonmal nicht schlecht aus.

Ich glaube dass er das bei mir nicht als konstanten Ausdruck wertet, 
sonst hätten sich die Werte nicht so geändert, kann aber auch daran 
liegen, dass ich momentan die Optimierung auf 0 habe.

Das Einzige was mich jetzt noch stört sind die anderen hohen Werte:
einmal die U64 Division unddie F64 Operationen.
Lässt sich da noch was amchen oder ist das nicht möglich, da es dafür 
evtl garkeine Hardware Unterstützung gibt?

von ChrisB (Gast)


Lesenswert?

Achso, das volatile hab ich natürlich auch davor, aber hab die Variablen 
lokal und nicht global, sollte aber beiden gehn denk ich

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

U64 und F64 wird in software gemacht... Könnte man aber wenns exessiv 
genuzt wird in nen Extra core auslagern.

von ChrisB (Gast)


Lesenswert?

Vielen Dank erstmal für deine Hilfe, hat mich wirklich ein gutes Stück 
weiter gebracht.
Naja, denke das ist vorerst nicht nötig ist U64 und F32 in Hardware zu 
erledigen, aber wenn, dann würde man das über diesen FSL Link machen 
oder?

Ich lasse den Microblaze im Moment mit 50 MHz laufen, den SDRam 
Controller mit 100MHz, das geht ganz gut so und ich konnte so auch noch 
etwas Performance rausholen.
Der Microblaze könnte auch noch etwas schneller laufen, aber der SDRam 
Controller will nicht schneller glaube nicht. Leider muss, so wie ich 
das sehe, die Frequenz des SDRam Controllers durch die Frequenz des 
Microblaze teilbar sein, deswegen kann ich den Microblaze im Moment 
nicht schneller laufen lassen oder ist diese Annahme falsch?
Kann man den Microblaze auch mit 75MHz laufen lassen und den SDRam mit 
100MHz?

Nutzt du die Library die Xilinx für die IPCores mitliefert? Was hälst du 
von diesen Libraries?
Ich finde die irgendwie sehr unpraktisch und unübersichtlich. Ich habe 
jetzt für die IPCores die ich verwende eigene Libs geschrieben und komme 
damit sehr viel besser klar, und schneller sind die alle mal...

von Hannes P. (hpauli)


Lesenswert?

ChrisB wrote:
> Hallo,
> ...
> Zuweisung "i=1;"       92 Takte
> SDRam 32Bit schreiben  127 Takte
> SDRam 32Bit lesen      99 Takte
> Float multiplizieren   28795 Takte
> Float dividieren       18091 Takte
>
> Diese paar Werte sollen erstmal reichen.
> Was mir direkt aufgefallen war ist, dass die Werte allgemein doch sehr
> hoch sind. Wie kommen diese hohen Werte zustande? Vor allem bei den
> Float-Multiplikation gibt Xilinx an, dass diese in 4 takten, die
> Division in 28 Takten zu schaffen sei. Da bin ich aber doch sehr weit
> entfernt, obwohl der Haken bei FPU in den Microblaze Einstellungen
> vorhanden ist.
> Aber auch das Lesen und Schreiben vom SDRam müsste doch in 10 Takten zu
> schaffen sein oder etwa nicht? Mache ich bei der Auswertung etwas
> falsch? Bei der Opitimiereng die der Compiler vornehmen kann habe ich
> alle Einstellungen ausprobiert, jedoch ohne großartige Änderungen.
> Vielleicht hat ja von euch jemand eine Idee, was hier schief geht...
> Gruß, Christoph

scheint mir ja auch wirklich arg lang zu sein...
hast du schon den Parameter 'C_AREA_OPTIMIZED = 0' gesetzt?
damit sollte die Taktzahl um einiges runtergehen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Hannes Pauli wrote:
> ChrisB wrote:
[..]
> scheint mir ja auch wirklich arg lang zu sein...
> hast du schon den Parameter 'C_AREA_OPTIMIZED = 0' gesetzt?
> damit sollte die Taktzahl um einiges runtergehen.
Schon längst geklärt wodran es gelegen hat ;)


@ChrisB:
Sorry ich fürchte da kann ich dir nicht weiterhelfen habe mich mit SDRam 
bisher noch garnicht beschäftigt. Die IP Cores habe ich bisher entweder 
in ASM oder direkt über In/Out in C angesprochen, die Libs von Xilinx 
sind mir da immer etwas zu undurchsichtig gewesen...

Ob man das ganze über den FSL Link oder über PLB/OPB macht ist ne 
Geschmacks und aufwandsfrage...
OPB für "langsame" Perepherie wie Timer, UARTs etc, und PLB für die 
schnellen Sachen wie DMA haben halt den Vorteil das sie Memmory Mapped 
angesprochen werden können, dafür ist das Interface recht komplex.
Beim FSL muß man halt den Zugriff selber regeln, dafür ist das Interface 
sehr simpel und ich benutz das gerade für meine Diplomarbeit, ist 
eigentlich wenn man sich ein paar Gedanken macht ne feine Sache.

von ChrisB (Gast)


Lesenswert?

Ja, ist schon geklärt, aber der C_AREA_OPTIMIZED Parameter ist auf 0.

Ich mache mir gerade ein paar Gedanken ob die Performance des Microblaze 
nun ausreichen wird oder nicht. Mal angenommen der Microblaze muss 
dauerhaft mit 115200 per Uart kommunizieren (Interrupt-gesteuert mit 
Ringpuffern) dann hat der, wenn er mit 50MHz läuft und die oben 
genannten Zeiten benötigt doch so einiges zu tun denk ich...
Um dann noch großartig zu rechnen, auf einem Display was darzustellen 
oder ein RTOS aufzusetzen ist da wahrscheinlich nicht mehr so viel 
Performance oder?
Aber wahrscheinlich kann ich das erst sagen, wenn ich das praktisch mal 
ausprobiert habe.
Im schlimmstne Fall muss ich vom Spartan 3 mit SDRam auf einen Viertex5 
mit DDR2 Ram umsteigen, da sollte dann doch einiges mehr drin sein denk 
ich mal.

Ich werde weitere Ergebnisse hier berichten.

von Christian R. (supachris)


Lesenswert?

Naja, der MicroBlaze ist halt nur ein Softcore, da ist ja einiges etwas 
beschränkt. Gibts denn da keinen DMA Controller, wie den MPMC beim 
Virtex 4? Da könntest du die CPU schon recht gut entlasten.

Wir arbeiten hier mit dem Virtex 4 FX20, da geht schon gut die Post ab. 
Einmal eingestellt, streamt der MPMC die Daten vom GbE MAC zur externen 
Hardware und zurück per DMA, und die CPU langweilt sich. Die UDP/IP 
Frames werden wo es geht durch den Scatter-Gather DMA zusammengebastelt.

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.