Desculpe pelo longo post, mas eu queria incluir tudo o que achava relevante desde o início.
O que eu quero
Estou implementando uma versão paralela dos métodos de subespaço de Krylov para matrizes densas. Principalmente GMRES, QMR e CG. Percebi (após a criação de perfil) que minha rotina DGEMV era patética. Então eu decidi me concentrar nisso, isolando-o. Eu tentei executá-lo em uma máquina de 12 núcleos, mas os resultados abaixo são para um laptop Intel i3 de 4 núcleos. Não há muita diferença na tendência.
Minha KMP_AFFINITY=VERBOSE
saída está disponível aqui .
Eu escrevi um pequeno código:
size_N = 15000
A = randomly_generated_dense_matrix(size_N,size_N); %Condition Number is not bad
b = randomly_generated_dense_vector(size_N);
for it=1:n_times %n_times I kept at 50
x = Matrix_Vector_Multi(A,b);
end
Eu acredito que isso simula o comportamento do CG por 50 iterações.
O que eu tentei:
Tradução
Originalmente, eu escrevi o código em Fortran. Traduzi para C, MATLAB e Python (Numpy). Escusado será dizer que MATLAB e Python foram horríveis. Surpreendentemente, C foi melhor que FORTRAN em um ou dois segundos para os valores acima. Consistentemente.
Criação de perfil
Eu criei um perfil do meu código para executar e ele foi executado por 46.075
segundos. Foi quando MKL_DYNAMIC foi definido comoFALSE
e todos os núcleos foram usados. Se eu usei o MKL_DYNAMIC como verdadeiro, apenas (aprox.) Metade do número de núcleos estava em uso em um determinado momento. Aqui estão alguns detalhes:
Address Line Assembly CPU Time
0x5cb51c mulpd %xmm9, %xmm14 36.591s
O processo mais demorado parece ser:
Call Stack LAX16_N4_Loop_M16gas_1
CPU Time by Utilization 157.926s
CPU Time:Total by Utilization 94.1%
Overhead Time 0us
Overhead Time:Total 0.0%
Module libmkl_mc3.so
Aqui estão algumas fotos:
Conclusões:
Sou iniciante em criação de perfil, mas percebo que a velocidade ainda não é boa. O código seqüencial (1 núcleo) termina em 53 segundos. Isso é uma velocidade menor que 1.1!
Pergunta real: O que devo fazer para melhorar minha aceleração?
Coisas que acho que podem ajudar, mas não tenho certeza:
- Implementação de Pthreads
- Implementação MPI (ScaLapack)
- Ajuste manual (não sei como. Por favor, recomende um recurso, se você sugerir isso)
Se alguém precisar de mais detalhes (principalmente em relação à memória), informe-me o que devo executar e como. Eu nunca tenho memória perfilada antes.