Cortex-M4: atomares Load oder Store

#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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren