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?