Técnicas para desenvolvimento e aceleração de códigos científicos
|
Nesta atividade, verificaremos como a vetorização de código pode melhorar o desempenho de aplicações científicas.
Processadores modernos possuem instruções e unidades funcionais vetoriais que são capazes de carregar e realizar operações com múltiplos dados consecutivos na memória (vetores) de uma só vez. Por exemplo, a instrução addpd xmm1, xmm2/m128 (Packed single-precision floating point add) é uma instrução dos processadores x86 modernos capaz de somar quatro valores de ponto flutuante simples (float) em uma única instrução. Os registradores xmm são registradores de 128 bits que são capazes de armazenar quatro valores de ponto flutuante simples (32 bits).
Nesta atividade, compararemos o desempenho de um algoritmo de produto interno de vetores ingênuo com o mesmo algoritmo vetorizado manualmente.
Cada atividade possui um arquivo com código fonte para executar o algoritmo, medir o tempo de execução e reportar o tempo e o desempenho do acesso à memória, em Gigabytes por segundo (GB/s). O algoritmo é executado múltiplas vezes e os tempos médio, menor e maior são reportados.
gcc -O3 kernel6-inner_prod.c -o kernel6-inner_prod.x
Ao inspecionar o código do programa, você pode observar que:
Qual foi a maior vazão da memória atingida em seu computador?
gcc -O3 kernel7-inner_prod_vec.c -DMMC_USE_SSE -msse3 -o kernel7-inner_prod_vec.x
Ao inspecionar o código do programa, você pode observar que:
Execute este kernel e compare o desempenho do mesmo com o desempenho do produto interno ingênuo.
Qual a relação de desempenho entre este algoritmo e o algoritmo ingênuo?
Os programas acima executam a rotina clean_caches() para remover os dados da cache antes de executar a próxima iteração do kernel. O que acontece com o desempenho dos programas acima se deixarmos de remover os dados da cache entre iterações do kernel?
Inspecione o código em linguagem de montagem compare com o código em C.
Para gerar o código em linguagem de montagem, execute:
gcc -O3 -DMMC_USE_SSE -msse3 kernel7-inner_prod_vec.c -S -o kernel7-inner_prod_vec.sProcure pelas rotinas inner_prod (algoritmo ingênuo) e inner_prod_vec. Você consegue identificar o laço principal de cada rotina?