Domanda

Come si fa a dire al compilatore di unroll loop in base al numero di iterazioni o qualche altro attributo? Oppure, Come si fa a trasformare il ciclo srotolamento ottimizzazione in Visual Studio 2005

EDIT:. Per esempio

//Code Snippet 1
    vector<int> b;
    for(int i=0;i<3;++i) b.push_back(i);

A differenza

//Code Snippet 2
    vector<int> b;
    b.push_back(0);
    b.push_back(1);
    b.push_back(2);

push_back () è un esempio, potrei sostituirlo con qualche cosa che può richiedere molto tempo.

Ma ho letto da qualche parte che posso usare Code 1 e il compilatore può srotolarlo al codice 2 se il ciclo soddisfa alcuni criteri. Quindi la mia domanda è: come si fa a farlo? C'è già una discussione su SO da quale è più efficiente, ma eventuali commenti su questo è apprezzato in ogni caso.

È stato utile?

Soluzione

E 'generalmente abbastanza semplice: "Si attiva ottimizzazioni"

Se dite al compilatore di ottimizzare il codice, quindi svolgimento del ciclo è una delle molte ottimizzazioni si cerca di applicare.

Occorre tuttavia tenere presente, che srotolamento non è sempre sta per produrre codice più veloce. Potrebbe causare cache miss (in entrambi i dati e cache istruzioni). E con il branch prediction avanzata trovato nella moderna CPU, i costi dei rami che compongono un ciclo è spesso trascurabile.

A volte, il compilatore può stabilire che srotolamento sarebbe produrre codice più lento, e allora non lo farà.

Altri suggerimenti

Di solito è sufficiente lasciare che il compilatore per il suo lavoro. Se il numero di cicli è noto al momento della compilazione e ottimizzazioni di compilatore sono attivati, il compilatore bilanciare code-dimensioni con riduzione ramo e srotolare i loop unrollable.

Se questo non è in realtà ciò che si vuole, c'è anche la possibilità di fare da soli con dispositivo di Duff: (da wikipedia)

send(to, from, count)
register short *to, *from;
register count;
{
    register n=(count+7)/8;
    switch(count%8){
    case 0: do{ *to = *from++;
    case 7:     *to = *from++;
    case 6:     *to = *from++;
    case 5:     *to = *from++;
    case 4:     *to = *from++;
    case 3:     *to = *from++;
    case 2:     *to = *from++;
    case 1:     *to = *from++;
        }while(--n>0);
    }
}

In questo modo si srotola con runtime determinata conta di iterazione.

Se ancora compilare in tempo svolgimento che si desidera, e il costruito nel ottimizzazioni non sono ciò che si vuole (se si vuole un controllo più dettagliato), è possibile creare un modello di C ++ per fare quello che vuoi. Questo è un modello di applicazione piuttosto banale, e dal momento che è tutto fatto al momento della compilazione, non si perde alcuna funzione inline o di altre ottimizzazioni che il compilatore potrebbe fare in aggiunta.

srotolamento Loop non sarà magicamente rendere il codice eseguito nella corsa circuito più veloce. Tutto ciò che fa è quello di salvare un paio di cicli di CPU utilizzate per confrontare la variabile del ciclo. Quindi ha senso solo nei cicli molto stretti in cui il corpo del ciclo si fa quasi nulla.

Per quanto riguarda il tuo esempio: mentre push_back() prende ammortizzato costante di tempo, questo non include il ciclo di allocare-copia-deallocare occasionale, più la copia degli oggetti reali. Ho molto dubbio che i paragoni nel ciclo svolgono un ruolo significativo rispetto a quello. E se non viene sostituito con qualsiasi altra cosa di prendere un lungo periodo di tempo, lo stesso vale.

Naturalmente, questo potrebbe essere sbagliato su qualsiasi CPU specifica e destro su qualsiasi altro. Con le idiosincrasie di moderne architetture CPU con loro cache, tubazioni di istruzioni e schemi predittivi ramo è diventato molto difficile outsmart il compilatore di ottimizzazione del codice. Che si sarebbe tentare di ottimizzare un ciclo con un corpo "pesante" srotolando sembra essere un suggerimento che non si conosce abbastanza per ottenere molto in questo. (Sto cercando difficile dirlo in modo da non si offenderà. Sono il primo ad ammettere che io sono un perdente in questo gioco di me stesso.)

In caso di problemi con le prestazioni, IME in 9 casi su 10, eliminando gli errori sciocchi (come la copia di oggetti complessi) e l'ottimizzazione di algoritmi e strutture dati è ciò che si dovrebbe guardare.

(Se credete ancora il problema rientra nella categoria 1-out-of-10, quindi provare il compilatore Intel. L'ultima volta che ho guardato è possibile scaricare una versione di prova gratuita, è collegato a VS, molto è stato facile da installare, e ha portato circa lo 0,5% di aumento di velocità nell'applicazione ho provato in.)

Si noti che si dice:

  

push_back () è un esempio, potrei sostituirlo con qualche cosa che può richiedere molto tempo.

In realtà, se push_back () (o quello che sostituirlo con) richiede molto tempo, questa è una situazione in cui svolgimento del ciclo sarebbe uno spreco di energie. Loop generalmente non è particolarmente lento; i tempi in cui svolgimento del ciclo ha senso è dove il lavoro svolto all'interno del ciclo è molto piccolo -. in questo caso i costrutti di loop potrebbero iniziare a dominare la trasformazione di quel tratto di esecuzione

Come sono sicuro che si otterrà in molte altre risposte - non preoccupatevi di questo tipo di cose a meno che effettivamente scopre che si tratta di un collo di bottiglia. Il 99% del tempo, non sarà.

Fare clic destro sul progetto, selezionare Proprietà e navigare: alt text http://img200.imageshack.us/img200/8685/propsm.jpg

ciclo WRT srotolamento, si noti che è generalmente accettato che con MS Visual Studio ottimizzazione per le dimensioni piuttosto che la velocità effettivamente produce codice più veloce a causa di riscontri nella cache / miss.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top