merkwürdiger Aufruf vor Speicherzugriffen

Gast #3619544
Lesenswert?
• ▲
▼
Hallo,

vor einem Schreibzugriff (SRAM) auf eine Struktur wird in Atmels ASF 
(z.B. bei den FIFOs) dieser Befehl aufgerufen:
1
    // Must be the last thing to do.
2
    barrier();

Wenn man sich diesen in der compiler.h anschaut, verbirgt sich das hier 
dahinter:
1
/**
2
 * \def barrier
3
 * \brief Memory barrier
4
 */
5
#if defined(__GNUC__)
6
#  define barrier()        asm volatile("" ::: "memory")
7
#elif defined(__ICCAVR32__)
8
#  define barrier()        __asm__ __volatile__ ("")
9
#endif

Hat jemand eine Ahnung was hiermit bewirkt werden soll?
#3619649
Lesenswert?
• ▲
▼
Ich denke eher, dass es bei einer Barriere darum geht, den Compiler 
insofern einzuengen, dass er Speicherzugriffe nicht wahllos im Code 
rumschieben darf.

In
1
   i = 5;
2
   j = 8;

könnte der Compiler auch die Reihenfolge der Zuweisungen umdrehen, wenn 
ihm das besser in den Kram passt, weil er zb j (oder die Adresse von j) 
schon in einem CPU Register hatte.
1
...
2
   j = k;
3
   i = 5;
4
   j = 8;
5
...

Erwarten würde ich solche Dinge, wenn es in den STrukturen zb logische 
Querverbindungen gibt. Wenn also Werte von zb einem Gültigkeitsflag 
abhängen und es wichtig ist, dass die Wertzuweisung erfolgt, bevor das 
Flag auf gültig gesetzt wird. Dreht der Compiler aus irgendeinem Grund 
die Reihenfolge der Aktionen um, dann ergibt das einen logischen Fehler.
Gast #3619663
Lesenswert?
• ▲
▼
brechbunkt schrieb:
> Aber wenn ich diese Speicheradresse als "volatile" deklariere, sollte
> doch diese Adresse dann ebenfalls ganz sicher beschrieben sein. Oder?

Nein.

volatile garantiert dir keine Ausführungsreihenfolgen oder sonstiges 
zeitliches Verhalten.

volatile sagt nur, daß der Zugriff stattfinden muß. Wann (insbesondere 
vor welchen anderen Zugriffen), kannst du nicht damit steuern.
Gast #3619787
Lesenswert?
• ▲
▼
Der Barrier Befehl sorgt dafür, dass über diese Grenze KEINE 
Memory-Zugriffe verschoben werden. Sprich alles was vor Barrier codiert 
wurde, wird auch vorher ausgeführt, die Reihenfolge davor kann aber von 
der im Code hingeschriebenen abweichen, wenn der Compiler es für besser 
hält. Gerade, wenn er zusammenhänge nicht erkennen kann.

    value = 0815
    written = 1

kann dann zu

    written = 1
    value = 0815

werden. Der Compiler geht hier von unabhängigen Dingen aus. Was passiert 
aber bei sowas im 2. Thread:

    while ( written )
       ;
    read = value
    written = 0

Hier sind also entweder atomics oder barriers notwendig:

    value = 0815
    barrier()
    written = 1

Beim 2. Thread ist etwas ähnliches erforderlich.

Volatile sorgt lediglich dafür, dass ein Zugriff IMMER passiert. Auf 
Multiprozessorsystemen ist aber auch volatile mit Vorsicht zu genießen, 
da es sich nicht unbedingt um Cache-Kohärenz kümmern muss, es kann also 
auch ein schon veralteter Wert gelesen werden.

Dort ist z.B. ein atomic einem volatile vorzuziehen, da sich dieser auch 
um den Cache, etc. kümmert.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.