2013-03-07 22 views
10

C'è un modo per dire a clang di srotolare un loop specifico?clang: Force loop srotolare per loop specifico


Googling per una risposta mi dà opzioni da riga di comando che interesseranno l'intero compilatore e non un singolo ciclo.


C'è una domanda simile per GCC --- --- Tell gcc to specifically unroll a loop ma la risposta a condizione che ci non funziona con clangore.

Opzione 1 ha suggerito c'è:

#pragma GCC optimize ("unroll-loops") 

sembra essere silenziosamente ignorati. Infatti

#pragma GCC akjhdfkjahsdkjfhskdfhd 

viene ignorato silenziosamente.

Opzione 2:

__attribute__((optimize("unroll-loops"))) 

risultati in un avvertimento:

warning: unknown attribute 'optimize' ignored [-Wattributes] 

Aggiornamento

joshuanapoli fornisce una bella soluzione come iterare tramite template metaprogrammazione e C + +11 senza creare un ciclo. Il costrutto sarà risolto in fase di compilazione, risultando in un corpo ripetutamente in linea. Anche se non è esattamente una risposta alla domanda, essenzialmente raggiunge la stessa cosa.

Ecco perché accetto la risposta. Tuttavia, se ti capita di sapere come utilizzare un ciclo C standard (for, while) e obbligarlo a srotolarlo, condividi la conoscenza con noi!

+1

In genere, il compilatore ha un'idea molto precisa di quando è opportuno srotolare un ciclo e quando non è una buona idea.Qual è il caso speciale che stai cercando di risolvere in caso contrario? –

+0

Potrebbe non * forzare * lo srotolamento, ma '__attribute__ ((hot))' potrebbe valere la pena di provarlo. –

+1

@MatsPetersson Voglio misurare in modo esplicito il vantaggio dello srotolamento del ciclo. Lo srotolamento scritto a mano velocizza il codice 3 volte, ma il compilatore non lo capisce. – CygnusX1

risposta

8

Per un programma C++, è possibile srotolare i loop all'interno della lingua. Non avrai bisogno di capire le opzioni specifiche del compilatore. Ad esempio,

#include <cstddef> 
#include <iostream> 

template<std::size_t N, typename FunctionType, std::size_t I> 
class repeat_t 
{ 
public: 
    repeat_t(FunctionType function) : function_(function) {} 
    FunctionType operator()() 
    { 
    function_(I); 
    return repeat_t<N,FunctionType,I+1>(function_)(); 
    } 
private: 
    FunctionType function_; 
}; 

template<std::size_t N, typename FunctionType> 
class repeat_t<N,FunctionType,N> 
{ 
public: 
    repeat_t(FunctionType function) : function_(function) {} 
    FunctionType operator()() { return function_; } 
private: 
    FunctionType function_; 
}; 

template<std::size_t N, typename FunctionType> 
repeat_t<N,FunctionType,0> repeat(FunctionType function) 
{ 
    return repeat_t<N,FunctionType,0>(function); 
} 

void loop_function(std::size_t index) 
{ 
    std::cout << index << std::endl; 
} 

int main(int argc, char** argv) 
{ 
    repeat<10>(loop_function)(); 
    return 0; 
} 

Esempio con funzione di loop complicato

template<typename T, T V1> 
struct sum_t 
{ 
    sum_t(T v2) : v2_(v2) {} 
    void operator()(std::size_t) { v2_ += V1; } 
    T result() const { return v2_; } 
private: 
    T v2_; 
}; 

int main(int argc, char* argv[]) 
{ 
    typedef sum_t<int,2> add_two; 
    std::cout << repeat<4>(add_two(3))().result() << std::endl; 
    return 0; 
} 
// output is 11 (3+2+2+2+2) 

Utilizzando una chiusura invece di un oggetto funzione esplicita

int main(int argc, char* argv[]) 
{ 
    int accumulator{3}; 
    repeat<4>([&](std::size_t) 
    { 
    accumulator += 2; 
    })(); 
    std::cout << accumulator << std::endl; 
} 
+0

Sì, questo è il mio modo predefinito di farlo. Ma dato che sono già all'interno di un template con parametri che devono entrare nella funzione "loop_function", diventa davvero brutto ... ecco perché sto cercando una soluzione "più piacevole" :) – CygnusX1

+0

Se puoi usare C + +11, quindi è possibile utilizzare le funzioni di constexpr per ridurre il rumore della sintassi del template. – joshuanapoli

+0

Se alcuni parametri sono constexpr/template e alcuni sono parametri dinamici regolari ... o? – CygnusX1