Re: FOR Schleife beschleunigen? Kategorie: Programmierung (von André H. - 17.04.2007 1:00) | ||
Als Antwort auf FOR Schleife beschleunigen? von Detlef Bäthke - 13.04.2007 11:01 | ||
| ||
Hallo Detlef, > for i=startaddr ... startaddr+len-1 > { > if (i % 32)==0 and i > { > // Code entfernt > } > eeout(8,data[i]); // Assembler Funktion > } > Zwischen den 8 Clock-Pulsen liegt immer eine Pause von ca. 700us. > Es gibt keine weiteren Threads. > Was ist für diese Zeit verantwortlich? Alles vor und nach dem ausführen Deiner ASM-Routine. Also das startaddr+len+1, der "Mechanismus" der For-Schleife selbst, die If-Abfrage, Das Schieben der Daten auf den Stack für eeout() und zu guter letzt noch die alle Aktionen vor und nach dem Ausführen der eigentlichen ASM-Routine. (Registerwerte speichern und wiederherstellen etc.) > Wie kann man diese Pause verringern? Indem Du einiges optimierst. Aber es sind keine Pausen, sondern der Controller arbeitet in dieser Zeit schon. Bei Single-Threading gäbe es als erste Optimierung das Setzen der Prio auf 255. Das bringt aber lediglich etwa 1% Geschwindigkeitszuwachs. Als nächstes könntest Du die For-Schleife optimieren, indem Du den Endwert nicht bei jedem Schleifendurchlauf neu berechnest: len=startaddr+len; for i=startaddr ... <len {} Bei 32768 Durchläufen sollte das etwa 4Sekunden ausmachen, sprich schneller sein. Wenn Du die If-Bedingung weglä�t, wären das hier etwa 7 Sekunden Gewinn. Wenn Du bei eeout() den Parameter "8", welcher scheinbar für 8Bit steht, weglä�t, und diesen in der ASM-Routine einbindest, wären das wiederum etwa 600ms bei 32768 Durchläufen. > Als �bergangslösung habe ich die Schleifendurchläufe reduziert. > > i = startaddr; > while (i <= (endaddr - 31)) > { > // Code enfernt > eeoutarray (data[i], 32); // Assembler Funktion > if (i < 0x7FE0) > { > i = i + 32; > } > else > { > i = 0x7FFF; > } > } Aber hier verschwendest Du wieder Zeit, da eine While-Schleife mit zusätzlicher Addition für i=i + x ca. 50% länger braucht, als die vergleichbare For-Schleife. Wenn, dann solltest Du schon auf diese weise die Durchläufe reduzieren: len=startaddr+len; for i=startaddr ... <len step 32 { // Code enfernt eeoutarray (data, i,32); // Assembler Funktion } �brigenst wird es Dir nichts bringen, wenn Du data[i] Deiner ASM-Funktion übergibst, um 32 Byte von Data zu schreiben. Du mu� dann eher 3 Parameter übergeben, wenn die Funktion eeoutarray() auch flexibel sein soll: Array als Referenz, Index und Anzahl zu schreibender Bytes. > Bei den Eeprom 95256 (32768 Bytes) verkürzt sich dadurch > die Programmierzeit von 40s auf 9s. Das ist klar. Du Arbeitest dann au�erhalb des Betriebssystems. Allerdings komme ich bei Deiner ursprünglichen For-Schleife lediglich auf knapp unter ca. 28sec, da ich nur eine Dummy-Funktion nutzen konnte, da ich Deine ASM-Routine nicht kenne. Aber aus Deinen Angaben schlie�e ich dann, da� ein ASM-Aufruf zum Schreiben eines Bytes der ursprünglichen Schleife etwa 0,4ms beträgt. An Deiner Stelle würde ich auf jeden Fall blockweise auf das EEProm schreiben. Das Prüfen, ob das EEprom mit dem schreiben fertig ist, würde ich auf jeden Fall nicht nach dem Senden der Daten, sondern immer davor durchführen. Ich denke nämlich, da� Du das scheinbar so machst. Oder prüfst Du dies vielleich nicht? Ich kenne das 95256 nicht, jedoch schau mal, ob dieses einen Pagewrite unterstützt. Dadurch lä�t sich u.U. auch einiges an Zeit sparen, da man nicht für jedes Byte neu adressieren mu�, sondern nur einmal pro Page. MfG André H. Antworten bitte nur ins Forum! Fragen per EMail auf Forum-Postings werden nicht beantwortet! Das macht meine Heizung gerade | ||
Antwort schreiben Antworten: Re: FOR Schleife beschleunigen? (von Detlef Bäthke - 20.04.2007 9:28) |