Re: Berechnung mit Word anstelle Single bringt fast nichts 995 zu 724 Takte Kategorie: Programmierung Basic (von PeterS - 1.11.2010 11:43) | |
Als Antwort auf Berechnung mit Word anstelle Single bringt fast nichts 995 zu 724 Takte von Ernst H. - 30.10.2010 14:08
| |
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 | |
Antwort schreiben Antworten: Re: Berechnung mit Word anstelle Single bringt fast nichts 995 zu 724 Takte (von Ernst - 2.11.2010 19:45) Re: Berechnung mit Word anstelle Single bringt fast nichts 995 zu 724 Takte (von PeterS - 3.11.2010 9:50) Re: Berechnung mit Word anstelle Single bringt fast nichts 995 zu 724 Takte (von ThomasK - 15.10.2012 22:57) Re: Berechnung mit Word anstelle Single bringt fast nichts 995 zu 724 Takte (von PeterS - 16.10.2012 10:46) |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum