Effekt ist, dass die so markierte Variable nicht im RAM sondern im Flash
angelegt wird. Wird durch "normalen" C-Code auf solch eine Variable
zugegriffen, wird jedoch aus dem RAM gelesen und nicht aus dem Flash!
--------------------------------
Wird die variable also im Flash und im RAM angelegt? die variable
value im RAM hat dann dieselbe Adresse wie die variable value im Flash?
Sina A. schrieb:> Effekt ist, dass die so markierte Variable nicht im RAM sondern im Flash> angelegt wird.
Eine VARIABLE wird nicht im Flash angelegt, weil sie dort nicht GEÄNDERT
werden kann. Nur KONSTANTE kannst du ins Flash ablegen.
> Wird die variable also im Flash und im RAM angelegt?
Nein.
Eine VARIABLE, die du ein einziges Mal (z.B. bei der Initialisierung)
mit einem Wert beschreibst und dann nur noch liest, deren Initialwert
wird aus dem Flash ins RAM kopiert und dann eben nur noch gelesen.
ok,
wenn dann in dem Beispiel weiter unten im tutorial
1
#include<avr/pgmspace.h>
2
3
/* Byte */
4
constuint8_taBytePROGMEM=123;
5
6
voidfoo(void)
7
{
8
uint8_ta=aByte;
9
uint8_tb=pgm_read_byte(&aByte);
10
}
dann ist aByte erstmal eine constante im RAM? d.h. in a steht dann jetzt
der wert, der zufällig im RAM stand als die constante aByte angelegt
wurde?
und &aByte ist die Adresse der Konstanten aByte im RAM?
aber bei pgm_read_byte(&aByte) ist &aByte die Adresse im Flash?
Ich habe früher (tm) mal im generierten Code herum gestochert und
folgendes festgestellt:
Konstanten werden während der Initialisierung des Programms ins RAM
geholt und sind somit relativ (Zugriffszeit) schnell. Brauchen also
FLASH und RAM.
Kandidaten der Abteilung "progmem" bleiben wo sie hingehören und werden
nur auf Anfrage geholt. Natürlich mit all den zugehörigen (zeitlich)
Nachteilen.
Eigene Funktion, eigene Sequenzen - das kann dauern.
Mein Fazit aus dieser Erkenntnis war: FLASH nur wenn nötig
(RAM-Ersparnis).
Keine Ahnung, ob das heute (tm) noch gilt.
Ich vergaß:
Bis heute habe ich nur einmal (explizit) FLASH genutzt.
Das war als ich viel zusagen hatte. Also etliche Menüs mit Texten füllen
musste. Darstellung von kommentierten Werten. Bei der "bildhaften"
Ausgabe ist auch die Geschwindigkeit von untergeordneter Größe.
Dabei wurde es aber im FLASH recht eng. Musste dann den großen Bruder
verwenden.
@Sebastian S. (amateur)
>Konstanten werden während der Initialisierung des Programms ins RAM>geholt und sind somit relativ (Zugriffszeit) schnell. Brauchen also>FLASH und RAM.
Falsch. Das sind globale oder statische VARIABLEN mit einem
Initialisierungswert ungleich Null.
>Kandidaten der Abteilung "progmem" bleiben wo sie hingehören und werden>nur auf Anfrage geholt. Natürlich mit all den zugehörigen (zeitlich)>Nachteilen.
Kaum.
>Eigene Funktion, eigene Sequenzen
Ja.
>- das kann dauern.
Nein, denn ein lpm ist nur einen Takt langsamer als ein lds. Alles
anderes ist identisch (Adressberechnung).
>Mein Fazit aus dieser Erkenntnis war: FLASH nur wenn nötig>(RAM-Ersparnis).
Falsch. Immer wenn möglich!
>Keine Ahnung, ob das heute (tm) noch gilt.
Das "keine Ahnung" auf jeden Fall.
@Falk
Na dann bau' mal eine Schleife mit zwei/drei bestimmenden Konstanten aus
dem FLASH und alternativ aus dem normalen, konstanten Pool auf und stopp
die Zeit.
Sina A. schrieb:> void foo (void)> {> uint8_t a = aByte;> uint8_t b = pgm_read_byte (&aByte);> }
Das ist grob Fahrlässig falsch!
Du kannst nicht die Adresse einer Ram Variablen als Adresse von DAten im
Flash nutzen.
OK, du kannst (sehe ich ja), aber du wirst nicht das damit erreichen,
was du dir vorstellst, was du dir wünscht.
@Sina Anargo (sinapse)
>#include <avr/pgmspace.h>>/* Byte */>const uint8_t aByte PROGMEM = 123;
Konstante im Flash/Progmem.
>void foo (void)>{> uint8_t a = aByte;
Das geht so nicht, da kommt Unsinn raus!
> uint8_t b = pgm_read_byte (&aByte);
Das geht.
>dann ist aByte erstmal eine constante im RAM?
Flash.
> d.h. in a steht dann jetzt>der wert, der zufällig im RAM stand als die constante aByte angelegt>wurde?
Nö, aByte hat konstant 123.
>und &aByte ist die Adresse der Konstanten aByte im RAM?
Im Flash!
>aber bei pgm_read_byte(&aByte) ist &aByte die Adresse im Flash?
Eben!
@Georg G. (df2au)
>Ehe ihr euch total selbst verwirrt: Es gibt im aktuellen GCC das>Attribut FLASH. Dann kümmert ich der Compiler selbst um den passenden>Zugriff.
Stimmt, aber das geht an einigen Stellen schief, weil man leicht glauben
kann, daß es keinen Unterschied mehr zwischen RAM und Flash-Zugriffen
gibt. Gibt es aber, vor allem wenn man mit Pointern in Funktionen
hantiert. Jaja, dann gibt es die XMEM Dinger 8-0
vielleicht sehe ich das ja falsch aber steht da nicht viel Mist drin?
ich hatte es auch versucht zu korrigieren, bin aber nicht so der LaTex
oder HTML Freak
1. Fehler Buchstabenvertauschung
bei Controllern mit mehr als 64kiB Flash auch
ELMP. das ist kein el.mag.Puls
using the LPM, ELPM sollte wohl stimmen
2. Fehler
strcmp_P
/* Liefert true zurück, wenn string_im_ram gleich "Hallo Welt" ist. */
mit Sicherheit nicht wenn gilt:
The strcmp_P() function is similar to strcmp() except that s2 is pointer
to a string in program space.
und Mit strcmp (String Compare) können wir zwei Strings vergleichen. Der
Rückgabewert kann hierbei folgende Werte haben:
0 die Strings sind gleich
>0 das erste ungleiche Zeichen in str1 ist größer als in str2
<0 das erste ungleiche Zeichen in str1 ist kleiner als in str2
// ich musste bei strcmp immer auf Vergleich mit !true also false für 0
prüfen
Falk B. schrieb:>>- das kann dauern.>> Nein, denn ein lpm ist nur einen Takt langsamer als ein lds. Alles> anderes ist identisch (Adressberechnung).
Das ist weniger als die Hälfte der Wahrheit.
Gerade mit lds passt der Vergleich wirklich garnicht, denn dafür
braucht's keinerlei Adressberechnungen zur Laufzeit, weil die Adresse
als zur Build-Zeit berechnete Konstante Teil der Instruktion ist, d.h.:
Das Laden aus dem RAM in ein Register läuft wirklich in genau zwei
Takten vollständig ab.
Ein entsprechender Zugriff mit lpm auf den Flash ist hingegen nicht
möglich, weil es dafür keine direkte Adressierungsart gibt, sondern nur
indirekte. D.h.: vor dem eigentlichen Zugriff sind erstmal im Minimum
noch zwei Adressregister zu laden. Damit sind wir schon in diesem
optimalen Fall bei 2 (lds) vs. 5 (ldi,ldi,lpm) Takten. Dazu kommt aber
noch, dass u.U. (Flashzugriff jenseits 64kB) auch noch das
RAMPZ-SFIO-Register gesetzt werden muss, was mindestens weitere zwei
Takte (ldi,out) kostet. Damit sind wir dann schon bei 2 vs. 7 Takten,
also fast bei der vierfachen Laufzeit für den Flash-Zugriff.
Etwas besser würde deine Argumentation passen, wenn du lpm mit ld
verglichen hättest (Zugriff auf Strings und Arrays). Das ist beides
indirekte Adressierung, im einfachsten Fall unterscheidet sich das
wirklich nur um einem Takt. Aber: auch hier ist ggf. für lpm die Sache
mit dem Laden von RAMPZ nötig, das allerdings nur einmalig für mehrere
Zugriffe in einer Schleife und fällt deswegen nicht mehr so sehr in's
Gewicht. Viel schwerwiegender ist oft, dass bei lpm nur Postincrement
möglich ist, in vielen Fällen aber Predecrement eine deutliche
effizientere Umsetzung eines Algorithmus bezüglich der Prüfung einer
Abbruchbedingung ermöglicht.
Und ganz eklig wird es beim Vergleich zwischen lpm und ldd (Zugriff auf
Strukturen), weil es für lpm einfach nicht die Adressierungsart indirekt
mit Displacement gibt und das Displacement (also der Offset in die
Struktur) durch Laufzeitberechnungen gesetzt werden muss, und das u.U.
sogar mit 24Bit Berechnungsbreite (bei Flash>64k).
Dazu kommt dann noch das Problem der eingeschränkten Wahl der
Adressregister, denn lpm geht nur via Z, für RAM-Zugriffe kann man
hingegen auch Y und (eingeschränkt) X verwenden. Dieser Sachverhalt kann
durch nötige Registersicherungen u.U. weitere Perfomancenachteile
generieren.
---
Nein: der Zugriff auf Daten im Flash kann schon ganz erhebliche
Perfomance-Einbußen bescheren, darüber muß man sich im Klaren sein und
das kannst auch du nicht wegdiskutieren.
Zusammenfassend könnte man vielleicht sagen: relativ unkritisch sind
Flash-Zugriffe im Vergleich zu RAM-Zugriffen nur im Falle von
sequentiellen Zugriffen auf eine "größere" Datenmenge, das allerdings
auch nur dann, wenn sie mit aufsteigender Adressierung erfolgen kann.
Typische Anwendung natürlich: Strings kopieren oder vergleichen. Da ist
der Nachteil von Flashzugriffen tatsächlich "relativ" gering. Aber auch
hierbei sind es in einer engen Schleife immer noch:
loop:
lpm reg,Z+ ;3
br* loop ;2
vs:
loop:
ld reg,Z+ ;2
br* loop ;2
5 vs. 4 Takte, d.h.: 25% mehr Laufzeit für den Flash-Zugriff.
@ c-hater (Gast)
>Das ist weniger als die Hälfte der Wahrheit.
Die größere Hälfte (sic!) wollte ich dir überlassen ;-)
>Nein: der Zugriff auf Daten im Flash kann schon ganz erhebliche>Perfomance-Einbußen bescheren, darüber muß man sich im Klaren sein und>das kannst auch du nicht wegdiskutieren.
Für dich ist selbst ein zu 90% gefülltes Glas mit deinem
Lieblingsgetränk zu 10% leer, anstatt zu 90% voll. Mein Beileid.
>Zusammenfassend könnte man vielleicht sagen: relativ unkritisch sind>Flash-Zugriffe im Vergleich zu RAM-Zugriffen nur im Falle von>sequentiellen Zugriffen auf eine "größere" Datenmenge, das allerdings>auch nur dann, wenn sie mit aufsteigender Adressierung erfolgen kann.
Nö, auch Arrayzugriffe sind nahezu gleich schnell, denn dann wird so
oder so eine Adresse berechnet. Ob dann lpm mit 3 oder ld mit 2 Takten
genutzt wird, fällt kaum ins Gewicht.
>hierbei sind es in einer engen Schleife immer noch:>loop:> lpm reg,Z+ ;3
br* loop ;2
>loop:> ld reg,Z+ ;2> br* loop ;2>5 vs. 4 Takte, d.h.: 25% mehr Laufzeit für den Flash-Zugriff.
Die spielen bei 90% aller C-Progamme keine Rolle und relativieren sich
im Gesamtkontext auf bestenfalls 10% mehr CPU-Last.
Es ging mir auch gar nicht um das letzte Prozent Geschwindigkeit sondern
darum, die schwachsinnige Panikmache bei direkter Flash-Nutzung zu
kontern.
Falk B. schrieb:> Nö, auch Arrayzugriffe sind nahezu gleich schnell
Ähem, Arrayzugriffe sind ja typischerweise oft sequentielle Zugriffe auf
eine "größere" Datenmenge. Also genau der Fall, für den ich einen
relativ geringen Nachteil attestiert hatte.
Was also sucht das "Nö" am Anfang deines Satzes? Sprachfehler?
Verständnisproblem?
Und nein: nicht jeder Zugriff auf Arrays ist derart unkritisch.
Wahlfreier Zugriff auf kleine Arrays kann teuer werden bei Flash. Das
wäre dann nämlich wieder die ldd-Situation wie beim Zugriff auf
Strukturen. Aber so weit hast wohl schon garnicht mehr gelesen...
> Die spielen bei 90% aller C-Progamme keine Rolle
Das mag gut sein. Interessant sind eben genau die Fälle, wo es doch eine
Rolle spielt.
> und relativieren sich> im Gesamtkontext auf bestenfalls 10% mehr CPU-Last.
Das ist doch nun wirklich völliger Schwachsinn. Das hängt ja wohl sehr
stark vom Kontext des Aufrufs ab. Z.B. eben das o.g., also wahlfreier
Zugriff auf kleines Array und das dann in einer sehr häufig aufgerufenen
ISR. Da kann der Unterschied in der Laufzeit schon sehr leicht mal den
Unterschied zwischen "geht" und "geht nicht" für die Anwendung insgesamt
ausmachen...
Wenn dir das nicht klar ist: schweige still und schäme dich!
Ein Wort aus der Praxis: wer seinen Controller zu 90% auslastet, der
sollte sowieso schnellstmöglich einen größeren oder schnelleren nehmen.
Und wenn das Wohl oder Wehe einer ISR an ein paar Maschinenzyklen hängt,
dann erst recht. Sonst fällt er spätestens bei der nächsten (beliebigen)
Änderung auf die Nase...
Lothar M. schrieb:> Ein Wort aus der Praxis: wer seinen Controller zu 90% auslastet, der> sollte sowieso schnellstmöglich einen größeren oder schnelleren nehmen.> Und wenn das Wohl oder Wehe einer ISR an ein paar Maschinenzyklen hängt,> dann erst recht. Sonst fällt er spätestens bei der nächsten (beliebigen)> Änderung auf die Nase...
Das genau ist die Einstellung, die uns zu der Software geführt hat, die
wir heute haben.
Also zu Software, die in den letzten 40 oder 50 Jahren trotz inzwischen
um mehrere Größenordnungen gewachsener Leistung der Hardware genauso
Scheiß-lahm ist wie eben vor 40 oder 50 Jahren...
Schön für den Anbieter von Software, dass er da Entwicklungsaufwand
gespart hat, Scheisse für den Benutzer der Software. Nur gibt es eben
viel mehr Benutzer einer Software als Anbieter derselben Software.
Könnte gut sein, dass die sich diese Verarschung nicht endlos gefallen
lassen...
Und, wenn man ehrlich ist: auch als Anbieter von Software ist man doch
immer auch Benutzer von Software (nämlich den zur Entwicklung der
eigenen Software nötigen Werkzeuge) und ärgert sich regelmäßig darüber,
dass deren neueste Version mal wieder deutlich fühlbar langsamer
geworden ist, ohne einen signifikanten funktionalen Mehrwert zu bieten.
Sie kostet nur neues Geld...
Jedem, dem sie nicht vollständig in's Hirn geschissen haben, ist klar:
Das kann nicht endlos so weiter gehen. Irgendwann begreifen auch die
Dümmsten, dass sie hier massiv verarscht und abgezockt werden...
Falk B. schrieb:> Hast du den Artikel so verunstaltet?>> Ich hab es mal korrigiert.
darauf hoffte ich, ich schrieb ja
Joachim B. schrieb:> ich hatte es auch versucht zu korrigieren, bin aber nicht so der LaTex> oder HTML Freak
aber hast du nicht nur halbe Arbeit geleistet?
es war falsch!
/* Liefert true zurück, wenn string_im_ram gleich "Hallo Welt" ist. */
es fehlt IMHO
entweder /* Liefert false zurück, wenn string_im_ram gleich "Hallo Welt"
ist. */
oder wenn true bleiben soll
return !strcmp_P (string_im_ram, PSTR ("Hallo Welt"));
dann können die von mir/dir engefügten Kommentare auch raus
Die nachfolgende Funktion liefert 0 zurück, wenn string_im_ram gleich
"Hallo Welt" ist. Mit strcmp (String Compare) können wir zwei Strings
vergleichen. Der Rückgabewert kann hierbei folgende Werte haben:
0 die Strings sind gleich
>0 das erste ungleiche Zeichen in string_im_ram ist größer als in
"Hallo Welt"
<0 das erste ungleiche Zeichen in string_im_ram ist kleiner als in
"Hallo Welt"
es gilt ja:
The strcmp_P() function is similar to strcmp() except that s2 is pointer
to a string in program space.
zu
Falk B. schrieb:> Hast du den Artikel so verunstaltet?
ja aber das kann man auch anders schreiben, egal du bist eben die
Freundlichkeit in Person, nur warum immer so gefrustet, brauchst du das?
@Joachim B. (jar)
>> Hast du den Artikel so verunstaltet?>ja aber das kann man auch anders schreiben, egal du bist eben die>Freundlichkeit in Person, nur warum immer so gefrustet, brauchst du das?
Sind wir heute ein wenig empfindlich? So eine Sache klärt man besser auf
der Diskussionsseite des Artikels. Wenn dann eine Lösung abgestimmt ist,
bringt man sie in den Artikel. Solche Schmierzettel und Baustellen
gehören nicht in den Artikel.
Falk B. schrieb:>>Freundlichkeit in Person, nur warum immer so gefrustet, brauchst du das?>> Sind wir heute ein wenig empfindlich?
nö, wollte ich nur mal anmerken, ist ja dein bevorzugter Schreibstil
welcher schon anderen "aufgefallen" ist.
Die Frage, "brauchst du das" ist unbeantwortet!
Falk B. schrieb:> So eine Sache klärt man besser auf> der Diskussionsseite des Artikels.
ich schrieb ja ich bin nicht so der alles wissen Typ und fand es sollte
korrigiert werden, wenn andere bessere Lösungen haben trete ich gerne
zurück, aber bis dahin stand es dort falsch!
Lieber eine
Falk B. schrieb:> verunstaltete
Korrektur als keine!
@ Joachim B. (jar)
>nö, wollte ich nur mal anmerken, ist ja dein bevorzugter Schreibstil>welcher schon anderen "aufgefallen" ist.
Ist eben so.
>Die Frage, "brauchst du das" ist unbeantwortet!
Was heißt "brauchen"? Es ist mein Stil, Dinge kurz und knapp und meist
politisch inkorrekt auf den Punkt zu bringen. Mag sein daß das dem einen
oder anderen Zeitgenossen zu ruppig ist.
https://de.wikipedia.org/wiki/Tacheles
Falk B. schrieb:> Was heißt "brauchen"? Es ist mein Stil, Dinge kurz und knapp
verstehe ich, mach ich auch zu oft
Falk B. schrieb:> meist> politisch inkorrekt auf den Punkt zu bringen
aber leider nicht nur, auch manchmal beleidigend
aber OK fachlich ist es ja meist passend!
Falk B. schrieb:> @Joachim B. (jar)>>>aber leider nicht nur, auch manchmal beleidigend>> War das Wort "verunstaltet" jetzt eine sooo arge Beleidigung für dich?
ne für mich war es grad noch OK
du hast es genau getroffen, mir war halt wichtig das der alte Unsinn da
nicht stehenbleibt ungeachtet von Schönheit!
aber mal unter uns, das hätte auch ohne deinen Kommentar korrigiert
werden können ohne die direkte Ansprache an mich oder?
wolltest du damit erreichen das eher Blödsinn in den Seiten stehen
bleibt und keiner mehr korrigieren mag um "Arbeit" zu vermeiden? :)
@Joachim B. (jar)
>du hast es genau getroffen, mir war halt wichtig das der alte Unsinn da>nicht stehenbleibt ungeachtet von Schönheit!
Ok.
>aber mal unter uns, das hätte auch ohne deinen Kommentar korrigiert>werden können ohne die direkte Ansprache an mich oder?
Mein Gott, leg doch mal nicht jedes Wort auf die Goldwaage!