Integração dos Enfoques




A integração da otimização de paralelismo e localidade de dados tem sido estudada por diversos pesquisadores [KENN93][LI93][MANJI95][MCKI92][WOLF92]. De uma maneira geral, os trabalhos adotam uma estratégia de otimização onde cada aspecto é tratado em separado, em fases distintas do processo de análise e tranformação. Ou seja, não há um enfoque unificado para tratamento da localidade de dados em conjunto com o paralelismo. Uma contribuição deste trabalho é propor uma alternativa a estas estratégias, onde procuramos adotar um esquema iterativo.

Como mencionado anteriormente, faremos o uso de transformações unimodulares. Esta classe de transformações provoca uma alteração na timing function T, que pode ser vista como uma forma diferente de proceder-se à varredura do espaço de iterações.

Com o intuito de facilitar a exposição de conceitos sobre a transformação, particularizaremos a análise para o caso das dependências que existem em um programa de multiplicação de matrizes, o qual será posteriormente objeto do exemplo de implementação do algoritmo completo proposto.

Dado a seguinte estrutura de loops:

for (i1=0; i1<N1; i1++)
  for (i2=0; i2<N2; i2++)
    for (i3=0;i3<N3; i3++)
      A[iA(1)][iA(2)]=A[iA(1)][iA(2)]+B[iB(1)][iB(2)]*C[iC(1)][iC(2)]
onde h: Z3 Z2, com:
		hA(i1,i2,i3) = (iA(1), iA(2))
		hB(i1,i2,i3) = (iB(1), iB(2))
		hC(i1,i2,i3) = (iC(1), iC(2))
Então, a transformação é definida por:

I' = I U

onde U é a matriz unimodular, I é o vetor com ordenamento original dos índices dos loops e I' é o vetor resultante da transformação aplicada.

Definamos a matriz de mapeamento M como:

h = I M

ou seja, a matriz M é aquela que multiplicada pelo vetor de índices fornece o vetor de mapeamento h.

O processo de transformação do ordenamento dos loops deve manter, contudo, o mapeamento em cada dependência, uma vez que é necessário a manutenção da semântica do programa. Assim, procedido à transformação, o mapeamento h calcula-se por:

h = I U U-1 M = I' M'

onde U-1 M = M' é a nova matriz de mapeamento.

Dispondo-se dessas definições podemos montar um algoritmo de otimização da localidade de dados, tendo como critério, a obtenção do menor custo da janela de referência:

Algoritmo: Otimização integrada de paralelismo e localidadade de dados

Entrada:

	número de loops K
	vetores de dependências D
	mapeamentos PI

{
/* determina o custo de cada uma das permutações permitidas dos loops */
for ( cada uma das permutações )
    if (transformação válida )
        determina custo em termos de acessos à memória
      else
        marca transformação com inválida
ordena as permutações válidas em ordem de custo
for ( cada uma das permutações )
    {
    obtém novos vetores de dependências
    if ( é possível paralelizar loop externo )
        break;   /* achou transformação adequada */
    }
if ( não é possível paralelizar loop externo )
    obtém transformação que paraleliza loop interno
obtém novos mapeamentos
re-otimiza loops internos em termos de memória
retorna versão do programa com o menor custo
}
Deste modo, teremos ao final, um código com a melhor localidade de dados passível de paralelização. Um procedimento mais genérico onde se levará em conta aspectos relacionados com a paralelização, tais como overheads de sincronização e de criação dos processos paralelos, e a incorporação de outras transformações está em desenvolvimento.





Pedro Vaz Artigas
E-mail: artigas@lsi.usp.br

LSI Laboratory of Integrated Systems