Cortex-M4: atomares Load oder Store

OP #7473735
Lesenswert?
• ▲
▼

Es geht um Cortex-M4+Fpu. Der g++ macht aus

1
   volatile uint64_t x1;
2
   volatile uint64_t x3;
3

4
int main(){
5
    while(true) {
6
        x3 = x1;
7
    }
8
}

ein

1
main:
2
ldr     r0, .L4 @ tmp118,
3
ldr     r1, .L4+4       @ tmp119,
4
.L2:
5
ldrd    r2, [r0]        @ x1.0_1, x1
6
strd    r2, [r1]        @ x1.0_1, x3
7
b       .L2             @

oder manchmal auch ein

1
vldr.64 d7, [r5]        @ int   @ x1.0_1, x1
2
vstr.64 d7, [r4]        @ int   @ x1.0_1, x3

wenn der Registerdruck zunimmt. Also ein atomares load oder store. Ich meine keine atomaren RMW-Zyklen, das kann der Cortex-M generell nicht (dazu existiert ldrex/strex oder IRQ-Sperre).

Die Frage nun: gibt es ein GCC-intrinsic, womit ich feststellen kann, bis zu welcher Größer ein fundamentaler DT atomar gelesen oder geschrieben werden kann. Auf einer 32-Bit CPU kann ich sicher 32-Bit annehmen, aber hier geht ja auch 64-Bit.

#7473778
Lesenswert?
• ▲
▼

Raoul D. schrieb:

Das wäre ja auch meine Vermutung gewesen. Ich bin nun etwas erstaunt, dass das auch für 64-Bit geht.

Tut es nicht. Weder LDRD noch VLDR ist atomar.

https://developer.arm.com/documentation/ddi0403/latest/ (siehe S. A3-80)

std::atomic<T>::is_always_lock_free dürfte ein guter Indikator für deine zweite Frage sein:

1
#include <atomic>
2

3
static_assert(std::atomic<uint32_t>::is_always_lock_free);
4
static_assert(std::atomic<uint64_t>::is_always_lock_free); // Fails on 32bit M4
#7481486
Lesenswert?
• ▲
▼

Arm schrieb:

LDRD wird als 2 Instruktionen ausgeführt, diese kann aber nicht durch eine exception unterbrochen werden (s. B1 - 543, im Kontrast zu LDM).

An der Stelle wird LDRD/STRD nicht erwähnt und in A3.5.3 (S.80) heißt es

1
LDM, LDC, LDC2, LDRD, STM, STC, STC2, STRD, PUSH, POP, VLDR, VSTR,
2
VLDM, VSTM, VPUSH, and VPOP instructions are executed as a sequence
3
of word-aligned word accesses.
4
(...)
5
If an instruction is executed as a sequence of accesses according to
6
these rules, some exceptions can be taken in the sequence and cause
7
execution of the instruction to be abandoned. On exception return,
8
the instruction that generated the sequence of accesses is re-executed
9
and so any accesses that had already been performed before the exception
10
was taken might be repeated.

Damit sollte LDRD auf single cores effektiv doch atomar sein?

Ich würde mich nicht darauf verlassen. Außerdem darf man "core" nicht zu eng sehen. Zum Beispiel ist DMA auch ein Bus Master, genau wie die CPU und beide sind (nur) per 32 Bit angebunden. Theoretisch(?) könnte ein Buffer per DMA gefüllt werden und zur Verarbeitung liest jemand mit LDRD.

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.