Forum: Mikrocontroller und Digitale Elektronik STM32 Profiling: Barriere gegen Optimierung?


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,

ich will auf meinem Cortex M4 bei einer Hand von Funktionen untersuchen, 
ob sich eine Optimierung lohnt. Dafür würde ich den Zyklen-Zähler 
verwenden. Jetzt stellt sich die Frage: Wie verhindere ich, dass der 
Compiler den Inhalt der Funktion vor oder hinter das Auslesen des 
Zyklenzählers verschiebt. Beispiel:
1
volatile struct
2
{
3
    int32_t max;
4
    int32_t min;
5
}
6
Cycles = {.max = 0, .min = INT32_MAX};
7
8
void foo()
9
{
10
    int64_t a = rand(), int64_t b = rand();
11
12
    volatile uint32_t startcyc = *DWT_CYCCNT;
13
14
    volatile int32_t c = a/b;
15
16
    volatile uint32_t stopcyc = *DWT_CYCCNT;
17
    int32_t cycles = (int32_t) (stopcyc - startcyc);
18
    Cycles.max = MAX( Cycles.max, cycles );
19
    Cycles.min = MIN( Cycles.min, cycles );
20
}
21
22
23
void bar()
24
{
25
    int64_t a = rand(), int64_t b = rand();
26
27
    volatile uint32_t startcyc = *DWT_CYCCNT;
28
29
    volatile int32_t c = functionOfInterest(a, b);
30
31
    volatile uint32_t stopcyc = *DWT_CYCCNT;
32
    int32_t cycles = (int32_t) (stopcyc - startcyc);
33
    Cycles.max = MAX( Cycles.max, cycles );
34
    Cycles.min = MIN( Cycles.min, cycles );
35
}



Bei foo() hat ja der Compiler jedes Recht, die Division vor das Auslesen 
des Zyklen-Zählers zu verlegen. Er muß ja nur die Zuweisung zu c 
dazwischenpacken. Gibt es eine Möglichkeit, solche Optimierungen zu 
verhindern, oder hilft hier nur Hoffen und das Lesen des 
Assembler-Listing?

Wie sieht es bei der zweiten Variante aus? Muß da der Funktionsaufruf 
zwischen den beiden volatile-Zugriffen erfolgen?

: Bearbeitet durch User
von leo (Gast)


Lesenswert?

Walter T. schrieb:
> Wie verhindere ich, dass der
> Compiler den Inhalt der Funktion vor oder hinter das Auslesen des
> Zyklenzählers verschiebt.

Stichwort: gcc memory barrier

leo

von Nop (Gast)


Lesenswert?

Walter T. schrieb:
> Gibt es eine Möglichkeit, solche Optimierungen zu
> verhindern

Nimm einfach so eine Compiler-Barrier jeweils vor und nach Deiner zu 
messenden Funtion:
1
#define CMPBAR __asm__ volatile("" : : : "memory")

von Walter T. (nicolas)


Lesenswert?

Danke, das war das Stichwort, das ich gesucht hatte.

von arm (Gast)


Lesenswert?

Nop schrieb:
> Walter T. schrieb:
>> Gibt es eine Möglichkeit, solche Optimierungen zu
>> verhindern
>
> Nimm einfach so eine Compiler-Barrier jeweils vor und nach Deiner zu
> messenden Funtion:
>
>
1
#define CMPBAR __asm__ volatile("" : : : "memory")

dafür stellt arm doch _DMB() im CMSIS bereit.

von Nop (Gast)


Lesenswert?

arm schrieb:

> dafür stellt arm doch _DMB() im CMSIS bereit.

Das macht noch mehr, weil es nicht nur eine Compiler-Barriere darstellt, 
sondern auch einen CPU-Befehl rauswirft. Die Frage war aber nach 
Umsortierung durch den Compiler.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.