__builtin_prefetch, quanto lê?

Estou tentando otimizar algum código RK4 GCC C ++ usando

__builtin_prefetch 

Estou com algum problema tentando descobrir como fazer a pré-busca de uma turma inteira. Eu não entendo o quanto o const void *addr é lido. Então, eu tenho os próximos valores de e to carregado.

 for (int i = from; i px- from->px; double delta = from->r + to->r - pos; double k1 = axcel(kv, delta, from->mass) * dt; //axcel is an inlined function double k2 = axcel(kv, delta + 0.5 * k1, from->mass) * dt; double k3 = axcel(kv, delta + 0.5 * k2, from->mass) * dt; double k4 = axcel(kv, delta + k3, from->mass) * dt; #define likely(x) __builtin_expect((x),1) if (likely(!from->bc)) { from->x += (( k1 + 2 * k2 + 2 * k3 + k4) / 6); } } 

Link: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/

Eu acho que apenas emite uma instrução de máquina FETCH , que basicamente busca um cache de linha, cujo tamanho é específico do processador.

E você poderia usar __builtin_prefetch (con[i+3].Pfrom) por exemplo. Pela minha (pequena) experiência, em tal loop, é melhor pré-buscar vários elementos antecipadamente.

Não use __builtin_prefetch muita freqüência (ou seja, não coloque muitos deles dentro de um loop). Meça o ganho de desempenho se você precisar deles, e use otimização GCC (pelo menos -O2 ). Se você tiver muita sorte, o manual __builtin_prefetch poderia aumentar o desempenho do seu loop em 10 ou 20% (mas também poderia prejudicá-lo).

Se tal loop for crucial para você, você pode considerar executá-lo em GPUs com OpenCL ou CUDA (mas isso requer a recodificação de algumas rotinas na linguagem OpenCL ou CUDA, e ajustá-las ao seu hardware em particular).

Use também um compilador GCC recente (a versão mais recente é a 4.6.2 ) porque está fazendo muito progresso nessas áreas.


(adicionado em janeiro de 2018 🙂

Ambos os hardwares (processadores) e compiladores fizeram muito progresso com relação aos caches, então parece que usar __builtin_prefetch é menos útil hoje (em 2018). Certifique-se de comparar.

Ele lê uma linha de cache. O tamanho da linha de cache pode variar, mas é mais provável que seja de 64 bytes em CPUs modernas. Se você precisar ler várias linhas de cache, confira prefetch_range .