Come impedire a gcc di ottimizzare alcune istruzioni in C?


107

Per sporcare una pagina (accendendo il dirty bit nella voce della tabella delle pagine), tocco i primi byte della pagina in questo modo:

pageptr[0] = pageptr[0];

Ma in pratica gcc ignorerà l'istruzione eliminando il dead store. Per evitare che gcc lo ottimizzi, riscrivo l'istruzione come segue:

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;

Sembra che il trucco funzioni, ma un po 'brutto. Vorrei sapere se esistono direttive o sintassi che hanno lo stesso effetto? E non voglio usare una -O0bandiera, dal momento che porterà anche grandi penalità alle prestazioni.


8
@Mark -O0 interromperà l'ottimizzazione, ma rallenterà anche le prestazioni del programma. Voglio solo impedire l'ottimizzazione di questo frammento di codice: P
ZelluX

Vorrei aggiungere che in passato, anche l'utilizzo -O0non ha impedito l '"ottimizzazione" del codice morto, ad esempio, quando GCC rileva che del codice non ha effetto, lo rimuove semplicemente. Per quanto ne so, questa è una fase anche prima -O0... Ma questa è solo la mia esperienza
smoothware

Risposte:


91

La disattivazione dell'ottimizzazione risolve il problema, ma non è necessario. Un'alternativa più sicura consiste nel rendere illegale per il compilatore l'ottimizzazione dell'archivio utilizzando il volatilequalificatore di tipo.

// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];

Il volatilequalificatore di tipo indica al compilatore di essere rigoroso riguardo agli archivi e ai carichi di memoria. Uno degli scopi di volatileè far sapere al compilatore che l'accesso alla memoria ha effetti collaterali e quindi deve essere preservato. In questo caso, l'archivio ha l'effetto collaterale di causare un errore di pagina e si desidera che il compilatore conservi l'errore di pagina.

In questo modo, il codice circostante può ancora essere ottimizzato e il tuo codice è portabile su altri compilatori che non comprendono GCC #pragmao la __attribute__sintassi.


2
Direi che è preferibile disattivare le ottimizzazioni. Puoi comunque beneficiare di altre ottimizzazioni utilizzando questo metodo.
Ben S

3
La soluzione di Dietrich Epp non funziona con il compilatore ARM4.1 . Anche la soluzione di ZelluX non funziona. Un metodo alternativo per far funzionare questo per ARM4.1 è nella soluzione di ZelluX, rendere " temp " una variabile volatile globale .
Oculus Dexter

1
Questo è piuttosto negativo per detto compilatore.
Alexey Frunze

1
@Shocker: GCC può ancora ottimizzare la variabile senza ottimizzare l'accesso effettivo alla memoria. Questi sono problemi diversi.
Dietrich Epp

2
@jww: questo utilizzo si adatta a quanto descritto in quel post del blog. volatilesignifica che l'accesso alla memoria deve avvenire come scritto, che è esattamente quello che vogliamo. In altre parole, ci abbiamo pensato attentamente e significa ciò che pensiamo significhi.
Dietrich Epp

184

Puoi usare

#pragma GCC push_options
#pragma GCC optimize ("O0")

your code

#pragma GCC pop_options

per disabilitare le ottimizzazioni a partire da GCC 4.4.

Consulta la documentazione di GCC se hai bisogno di maggiori dettagli.


3
Vale la pena notare, tuttavia, che questo funziona solo su intere funzioni, non su specifiche istruzioni: gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/… "Ogni funzione definita dopo questo punto è come se attributo (( ottimizzare ("STRING"))) è stato specificato per quella funzione. ".
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

134

Invece di usare i nuovi pragmi, puoi anche usare __attribute__((optimize("O0"))) per le tue esigenze. Questo ha il vantaggio di applicarsi solo a una singola funzione e non a tutte le funzioni definite nello stesso file.

Esempio di utilizzo:

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}

3
Cosa succede se non sto utilizzando -Olevelun'opzione ma ho utilizzato le opzioni individuali che si attiva separatamente? (Nel mio caso, non riesco a determinare quale sia l'opzione di ottimizzazione individuale che sta violando il codice) .
user2284570
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.