Kommentar: Einfügen von HTML im Kommentar: Link einfügen: <a href="LINKURL" target="_blank">LINKTITEL</a> Bild einfügen: <img src="BILDURL"> Text formatieren: <b>fetter Text</b> <i>kursiver Text</i> <u>unterstrichener Text</u> Kombinationen sind auch möglich z.B.: <b><i>fetter & kursiver Text</i></b> C Quellcode formatieren: <code>Quellcode</code> BASIC Quellcode formatieren: <basic>Quellcode</basic> (Innerhalb eines Quellcodeabschnitts ist kein html möglich.) Wichtig: Bitte mache Zeilenumbrüche, bevor Du am rechten Rand des Eingabefeldes ankommst ! -> I > Hallo Ernst, > > jetzt arbeite ich schon an einem Feiertag damit Deine plakativen Äußerungen und Dein > fehlerhafter Benchmark nicht unwidersprochen im Raum stehenbleiben. > > Der Fehler im Benchmark ist, das die Generierung von Debugcode im Test eingeschaltet > blieb, so wurden Bytecodes mitgemessen die zum SingleStep im Debugger dienen. Die neuen > Benchmarkergebnisse und den überarbeiteten Benchmark habe ich unten angefügt. Die neuen > Ergebnisse zeigen, das die alten Werte bis zu 40% (bei ++Var) zu hoch gemessen wurden. > > Zu Deiner Aussage "Berechnung mit Word anstelle Single bringt fast nichts 995 zu 724 Takte", > sorry Ernst, aber das ist Bild-Zeitungsniveau. Du kannst nicht eine Float Multiplikation > mit einer Word Multiplikation plus Division vergleichen, ohne darauf hinzuweisen, das es > hier um einen Spezialfall einer Berechnung gilt. Wenn ich solche allgemeinen Schlagzeilen > heraushaue, dann muß ich die gleichen Berechnungen vergleichen. Hier Word Multiplikation > plus Division = 649 Takte zu Single Mutliplikation plus Division = 1892 Takte, und da habe > ich einen Unterschied von Faktor 3! > > Word Mult: 303 > Word Mult + Div: 649 > Single Mult: 920 > Single Mult + Div: 1892 > > > Zu Deinem Problem mit "++Var" und "Var=Var+1". In den neuen Benchmarkergebnissen sieht man, das > "++Var" = 185 Takte deutlich schneller als "Var=Var+1" = 260 Takte ist. Was Du nicht wissen > kannst, ist das "++Var" ineffizienter ist, wenn man den Wert von Var vom Stack verwirft, also > nicht z.B. "Var2= ++Var" = 206 Takte schreibt. Dies ist deutlich effizienter als ein "Var2= Var" > und "Var=Var+1" mit insgesamt 395 Takten. > > ++Var: 185 > Var=Var+1: 260 > Var2= ++Var: 206 > "Var2= Var" und "Var=Var+1": 395 > > > Wie ich schon geschrieben habe, habe ich einen Overhead von 36 Takten, die für das Fetch Bytecode, > Table lookup, Sprung in den Bytecode drauf gehen. Inklusive ist Management von Interrupts und > Multitasking. Dieses Performance Problem haben alle Interpreter. Wegen der Harvard Architektur > schneidet der Atmel Mega darin noch ein wenig schlechter ab, als z.B. eine 32-Bit x86 Architektur. > > > > Korrekte Benchmark Messwerte: > ----------------------------- > > Mess1 ++Var (Byte) Takte= 185 12.543000us > Mess2 Var=Var+1 (Byte) Takte= 260 17.628000us > Mess3 2xPort_WriteBit Takte= 886 60.070800us > Mess4 2xPort_WriteBit ++Var Takte= 1071 72.613800us > Mess5 Port_Write Takte= 366 24.814800us > Mess6 DirAcc_Write Takte= 359 24.340200us > Mess7 PortBit Eigenbau Takte= 573 38.849399us > Mess8 Port_WriteBit Takte= 443 30.035400us > Mess9 Schleife 10000 N128= 3782 32.827758ms > Mess10 ULong=ULong+1 Takte= 409 27.730199us > Mess11 ULong vergleich Takte= 563 38.171401us > Mess12 Byte Vergleich Takte= 297 20.136600us > Mess13 ADC abfrage Takte= 2265 153.567001us > Mess14 Case abfrage Takte= 756 51.256801us > Mess15 If abfrage Takte= 1855 125.768997us > Mess16 ADC abfrage 8x Takte= 18375 1245.824951us > Mess17 Floatberech Takte= 920 62.375999us > Mess18 Word Mul/Div 2Komma Takte= 649 44.002201us > > > Überarbeiteter Benchmark: > ------------------------- > > 'Fertiges Programm zum Ausgeben von Messungen -einfach starten- > 'Ergebnis erscheint an Konsole > > Dim Zeitfloat As Single > Dim Timervar As Word > Dim Var As Byte ' für Tests Nr1 ++Var, und Var=Var+1 > Dim Var2 As Byte > Dim i As Integer ' For Schleife > Dim Schleife As Integer > Dim Longvar As ULong > Dim Longvar2 As ULong > Dim Pausenzeit As Word > Dim ADC_0 As Word > Dim Wordvar As Word > Dim Floatvar As Single > Dim txt(60) As Char > > #define Pausenzeit 1000 '2sec Pause zwischen den Messungen > #define Duchlaufe 3 > #define Ref 0.004887 'Referenzspannungsfaktor für ADC - Test > > > > > Sub main() > Do While (1) > Port_DataDir(PortC,255 ) 'PortC alles Output.. zum Messen > > Msg_WriteText("Mess1 ++Var (Byte) " ) > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'bei 65000 wird Int ausgelöst, hier nicht verwendet > ++Var 'hier die Prüf - Anweisungen oder ganze Programmteile > 'bis max 4,4ms 67,8ns Takt = 14,..MHz > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > 'nun Test2: > > Msg_WriteText("Mess2 Var=Var+1 (Byte) " ) > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > Var=Var+1 'hier die Prüf - Anweisungen oder ganze Programmteile > 'bis max 4,4ms 67,8ns Takt = 14,..MHz > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > 'nun Test3: > > > Msg_WriteText("Mess3 2xPort_WriteBit " ) > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > Port_WriteBit(20,1) 'hier die Prüf - Anweisungen oder ganze Programmt. > Port_WriteBit(20,0) 'PortC.4 auf 0 > 'bis max 4,4ms 67,8ns Takt = 14,..MHz > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > 'nun Test4: > Msg_WriteText("Mess4 2xPort_WriteBit ++Var" ) > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > Port_WriteBit(20,1) 'hier die Prüf - Anweisungen oder ganze Programmt. > ++Var 'mit Logkanalyser können die zusätzlichen 260Takte.. > Port_WriteBit(20,0) > 'bis max 4,4ms 67,8ns Takt = 14,..MHz > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > 'nun Test5: > Msg_WriteText("Mess5 Port_Write " ) > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > Port_Write(PortC,255 ) 'hier die Prüf - Anweisungen oder ganze Programmt. > 'bis max 4,4ms 67,8ns Takt = 14,7456MHz > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > 'nun Test6: > Msg_WriteText("Mess6 DirAcc_Write " ) > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > DirAcc_Write(0x35,255 ) 'hier die Prüf - Anweisungen oder ganze Progr. > 'bis max 4,4ms 67,8ns Takt = 14,..MHz > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > 'nun Test7: > Msg_WriteText("Mess7 PortBit Eigenbau " ) > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > DirAcc_Write(0x35,DirAcc_Read(0x35 Or 00010000 ) ) > 'das PortC Register wird gelesen maskiert und damit Bit 4 gesetzt > 'hier die Prüf - Anweisungen oder ganze Programmteile > 'bis max 4,4ms 67,8ns Takt = 14,..MHz > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > 'nun Test8: > Msg_WriteText("Mess8 Port_WriteBit " ) > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > Port_WriteBit(20,1) 'hier die Prüf - Anweisungen oder ganze Programmt. > 'bis max 4,4ms 67,8ns Takt = 14,..MHz > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > 'nun Test9: hier langsamerer Takt: 8,68us > Msg_WriteText("Mess9 Schleife 10000 " ) > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,5) ' Startpunkt der Messung mit 8,68usTakt > For Schleife = 1 To 10000'hier die Prüf - Anweisungen oder ganze Progr. > ++Var > Next 'bis zu 0,56sec > Msg_Laufzeit128T() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > 'nun Test10: > Msg_WriteText("Mess10 ULong=ULong+1 " ) > Longvar = 4294967294 ' damit in 2. Durchlauf ein Überlauf entsteht > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'hier die Prüf - Anweisungen oder ganze Programmteile > Longvar = Longvar + 1 'bis max 4,4ms 67,8ns Takt = 14,..MHz > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > 'nun Test11: > Msg_WriteText("Mess11 ULong vergleich " ) > Longvar = 4294967000 ' > Longvar = 4294967010 'eine hohe Zahl - es müssen alle 32 Bits vergl. > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'hier die Prüf - Anweisungen oder ganze Programmteile > If Longvar2 < Longvar Then 'bis max 4,4ms 67,8ns Takt = 14,..MHz > ++Var ' hier vergleich nicht erfüllt, Var bleibt gleich > End If > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > > > 'nun Test12: > Msg_WriteText("Mess12 Byte Vergleich " ) > Var = 222 ' > Var2 = 243 ' > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'hier die Prüf - Anweisungen oder ganze Programmteile > If Var2 < Var Then 'bis max 4,4ms 67,8ns Takt = 14,..MHz > ++Var ' hier vergleich nicht erfüllt, Var bleibt gleich > End If > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > > 'nun Test13: > Msg_WriteText("Mess13 ADC abfrage " ) ' > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'hier die Prüf - Anweisungen oder ganze Programmteile > ADC_Set(ADC_VREF_VCC,0) > ADC_0 = ADC_Read() > > 'Takte= 4008 271.742401us Takte= 2397 162.516601us Takte= 2382 161.49.. > 'beim ersten Aufruf 4008, dann nurmehr ca 2380 > > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > 'nun Test14: > Msg_WriteText("Mess14 Case abfrage " ) ' > Var=5 > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'hier die Prüf - Anweisungen oder ganze Programmteile > Select Case Var > Case 1 > ++Var2 > Case 2 > ++Var2 > Case 3 > ++Var2 > Case 4 > ++Var2 > Case 5 > ++Var2 > Case 6 > ++Var2 > End Select > > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > > 'nun Test15: > Msg_WriteText("Mess15 If abfrage " ) ' > Var=5 > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'hier die Prüf - Anweisungen oder ganze Programmteile > If Var = 1 Then > ++Var2 > End If > If Var = 2 Then > ++Var2 > End If > If Var = 3 Then > ++Var2 > End If > If Var = 4 Then > ++Var2 > End If > If Var = 5 Then > ++Var2 > End If > If Var = 6 Then > ++Var2 > End If > 'ist nicht exakt mit obiger Case vergleichbar, aber ähnlich > > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > 'nun Test16: > Msg_WriteText("Mess16 ADC abfrage 8x " ) ' > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'hier die Prüf - Anweisungen oder ganze Programmteile > ADC_Set(ADC_VREF_VCC,0) > ADC_0 = ADC_Read() > ADC_Set(ADC_VREF_VCC,1) > ADC_0 = ADC_Read() > ADC_Set(ADC_VREF_VCC,2) > ADC_0 = ADC_Read() > ADC_Set(ADC_VREF_VCC,3) > ADC_0 = ADC_Read() > ADC_Set(ADC_VREF_VCC,4) > ADC_0 = ADC_Read() > ADC_Set(ADC_VREF_VCC,5) > ADC_0 = ADC_Read() > ADC_Set(ADC_VREF_VCC,6) > ADC_0 = ADC_Read() > ADC_Set(ADC_VREF_VCC,7) > ADC_0 = ADC_Read() > > > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > > 'nun Test17: > Msg_WriteText("Mess17 Floatberech " ) ' > Wordvar=1023 > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'hier die Prüf - Anweisungen oder ganze Programmteile > Floatvar = Wordvar * Ref > 'Mess17 Floatberech Takte= 995 67.460998us Takte= 995 67.460998us > > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > Msg_WriteText("U=") > Msg_WriteFloat(Floatvar) > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > > > 'nun Test18: > Msg_WriteText("Mess18 Word Mul/Div 2Komma" ) ' > Wordvar=1023 > For i = 1 To Duchlaufe 'für 3-malige Ausgabe in einer Zeile > AbsDelay(2 ) ' unbedingt notwendig!!! nur mit 2ms Pause konstante Werte > Timer_T1Time(65000,1) ' Startpunkt der Messung 67,8ns Takt Cnt1 = 0 > 'hier die Prüf - Anweisungen oder ganze Programmteile > > ADC_0 = Wordvar * 64 /131 > 'Mess18 Word Mul/Div 2Komma Takte= 724 49.087200us Takte= 724 49.087200us > > Msg_Laufzeit1() ' Aufruf der Sub (Cnt Auslesung und Korrektur) > Next > > Msg_WriteText("U=") > Msg_WriteWord(ADC_0 ) > > Msg_WriteChar(13) 'CR ... Neue Zeile > AbsDelay(Pausenzeit ) 'Zeit zum ablesen > > Msg_WriteChar(13) 'CR ... Neue Zeile letzte Zusatzzeile > End While > End Sub 'main ************************************ > > Sub Msg_Laufzeit1 () ' Sub für Messung und Ausgabe > Timervar = Timer_T1GetCNT() - 230 ' Korr-Wert wenn kein Befehle > Str_Printf(txt, " Takte= %d %fus ", Timervar, Timervar * 0.0678) > Msg_WriteText(txt) > End Sub > > Sub Msg_Laufzeit128T () ' nur mit 2ms Pause am Beginn konstante Werte !! > Schleife = Schleife + 1 - 1 ' Zeitverbrauch damit wenige Takte abgezogen > Timervar = Timer_T1GetCNT() - 1 ' Korrektur -1 > Str_Printf(txt, " N128= %d %fms ", Timervar, Timervar * 0.00868) > Msg_WriteText(txt) > End Sub >