Sto testando varie ottimizzazioni in C/C++ utilizzando il compilatore GCC. Attualmente ho un ciclo con più istruzioni nidificate if. Le condizioni sono calcolate all'inizio dell'esecuzione del programma. Sembra alquanto simili:Ottimizza le istruzioni nidificate if in un ciclo in C/C++ con GCC
bool conditionA = getA();
bool conditionB = getB();
bool conditionC = getC();
//Etc.
startTiming();
do {
if(conditionA) {
doATrueStuff();
if(conditionB) {
//Etc.
} else {
//Etc.
}
} else {
doAFalseStuff();
if(conditionB) {
//Etc.
} else {
//Etc.
}
}
} while (testCondition());
endTiming();
Dove doATrueStuff()
è una funzione inline che fa qualche semplice calcolo numerico quindi non c'è overhead nella chiamata esso.
Sfortunatamente, le condizioni non possono essere definite in anticipo, devono essere calcolate durante il runtime. Non possiamo nemmeno prevedere in modo affidabile la possibilità che siano veri o sbagliati. getA()
potrebbe anche essere rand()%2
. Ma una volta calcolato, il loro valore non cambia mai.
Ci sono due soluzioni che ho pensato, uno dei quali puntatori a funzione globali che vengono utilizzati per chiamare la funzione appropriata all'interno del ciclo, in questo modo:
void (*ptrA)(void);
//Etc.
int main(int argc, char **argv) {
//...
if (conditionA) {
ptrA=&aTrueFunc;
} else {
ptrA=&aFalseFunc;
}
//...
do {
(*ptrA)();
} while (testCondition());
//...
}
In questo modo posso eliminare tutti i rami dalla loop, comunque avrò il sovraccarico di chiamate a funzioni multiple che mi rallentano.
O potrei semplicemente avere un ciclo diverso per ogni combinazione di condizioni, qualcosa di simile:
if(conditionA) {
if(conditionB) {
do {
//Do A == true B == true stuff
} while (testCondition());
} else {
do {
//Do A == true B == false stuff
} while (testCondition());
}
} else {
//Etc.
}
Tuttavia che è molto meno elegante e ottiene impossibile per uno per fare in modo efficiente una volta che si inizia ad avere troppo molte condizioni, poiché per le condizioni X è necessario scrivere 2^X cicli.
C'è un modo più elegante/più veloce per ottimizzare questo?
C'è addirittura qualche punto in questo o il compilatore in qualche modo capirà che la condizione non cambia durante il ciclo e la ottimizza da sola?
E per curiosità, esiste un altro linguaggio di programmazione che renderebbe la scrittura di tale codice più semplice/possibile? O sarebbe possibile solo usando l'assembly per cambiare le istruzioni del programma una volta caricato in memoria?
La prima idea non sembra avere più chiamate di funzione dell'originale. –
La CPU probabilmente andrà molto bene con la previsione delle diramazioni se le condizioni non cambiano all'interno del ciclo. – Carlton
Sembra che tu abbia già i tuoi 2^X blocchi diversi. – Jarod42