Ajude a manter o site livre, gratuito e sem propagandas. Colabore!
OpenMP permite paralelizar laços de forma simples e eficiente. A diretiva omp for
pode ser usada para dividir o trabalho entre os threads disponíveis. Por exemplo, consideremos o seguinte código que implementa um método para a multiplicação de uma matriz por um vetor de elementos.
Na linha 9 do código, a diretiva omp parallel for
indica que o laço for
deve ser paralelizado. O compilador divide o laço entre os threads disponíveis. Cada thread computa uma parte dos produtos internos entre as linhas da matriz e o vetor.
A distribuição do laço entre as threads pode ser feita de diferentes formas e é definida pela cláusula schedule(type,[n]), que aceita as seguintes opções:
static, [n]: o laço é dividido em pedaços iguais de n itens sequênciais. Todos os pedaços são distribuídos de forma sequêncial entre os threads. Ou seja, o primeiro pedaço vai para o primeiro thread, o segundo pedaço vai para o segundo thread e assim por diante. Quando todos os threads tiverem recebido um pedaço, o processo recomeça com o primeiro thread. O padrão é n = ceiling(num_of_iterations/num_of_threads).
dynamic, [n]: o laço é dividido em pedaços de n itens sequênciais. Cada thread recebe um pedaço até que todos os pedaços sejam distribuídos. No entanto, a distribuição dos pedaços entre os threads é feita de forma dinâmica, ou seja, cada thread pode pegar um novo pedaço assim que terminar o anterior. O padrão é n = 1.
guided, [n]: o laço é dividido em pedaços de n itens sequênciais. Cada thread recebe um pedaço até que todos os pedaços sejam distribuídos. No entanto, a distribuição dos pedaços entre os threads é feita de forma guiada, ou seja, cada thread pode pegar um novo pedaço assim que terminar o anterior. No entanto, o tamanho do próximo pedaço a ser pego diminui a cada iteração. Por padrão, o primeiro pedaço tem tamanho n = ceiling(num_of_iterations/num_of_threads) e os próximos têm camanho ceiling(num_of_iterations_left/num_of_threads).
auto: a divisão entre as threads é delegada ao compilar e ao sistema.
Uma redução é uma operação que combina os resultados de várias threads em um único resultado. Por exemplo, a soma dos elementos de um vetor é uma operação de redução. A diretiva omp reduction
pode ser usada para especificar uma operação de redução em um laço.
Por exemplo, o seguinte código implementa um método para computar o produto interno entre dois vetores de elementos.
Na linha 9 do código, a diretiva omp parallel for reduction(+:result) indica que o laço for deve ser paralelizado e que a variável result deve ser reduzida. A operação de redução é especificada entre parênteses. Neste caso, a operação de redução é a soma. A variável result é inicializada em cada thread e, ao final do laço, os resultados parciais são somados para obter o resultado final. Reduções com as operações *, /, - também são suportadas.
Teste a eficiência do Código 5 para diferentes tamanhos de matrizes. O que ocorre quando aumenta? E quando aumenta?
Teste a eficiência do Código LABEL:cap_mp:cod:matVec para diferentes tipos de distribuição de laços pela cláusula schedule. Qual é a mais eficiente em seu computador? Porquê?
Desenvolva um método com OpenMP/C++ para computar a integral de uma função em um intervalo pela regra composta de Simpson22endnote: 2Thomas Simpson, 1710 - 1761, matemático britânico. Fonte: Wikipédia: Thomas Simpson. com um número arbitrário de subintervalos . Use a diretiva omp parallel for
para paralelizar os laços de redução.
Aproveito para agradecer a todas/os que de forma assídua ou esporádica contribuem enviando correções, sugestões e críticas!
Este texto é disponibilizado nos termos da Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional. Ícones e elementos gráficos podem estar sujeitos a condições adicionais.
Ajude a manter o site livre, gratuito e sem propagandas. Colabore!
OpenMP permite paralelizar laços de forma simples e eficiente. A diretiva omp for
pode ser usada para dividir o trabalho entre os threads disponíveis. Por exemplo, consideremos o seguinte código que implementa um método para a multiplicação de uma matriz por um vetor de elementos.
Na linha 9 do código, a diretiva omp parallel for
indica que o laço for
deve ser paralelizado. O compilador divide o laço entre os threads disponíveis. Cada thread computa uma parte dos produtos internos entre as linhas da matriz e o vetor.
A distribuição do laço entre as threads pode ser feita de diferentes formas e é definida pela cláusula schedule(type,[n]), que aceita as seguintes opções:
static, [n]: o laço é dividido em pedaços iguais de n itens sequênciais. Todos os pedaços são distribuídos de forma sequêncial entre os threads. Ou seja, o primeiro pedaço vai para o primeiro thread, o segundo pedaço vai para o segundo thread e assim por diante. Quando todos os threads tiverem recebido um pedaço, o processo recomeça com o primeiro thread. O padrão é n = ceiling(num_of_iterations/num_of_threads).
dynamic, [n]: o laço é dividido em pedaços de n itens sequênciais. Cada thread recebe um pedaço até que todos os pedaços sejam distribuídos. No entanto, a distribuição dos pedaços entre os threads é feita de forma dinâmica, ou seja, cada thread pode pegar um novo pedaço assim que terminar o anterior. O padrão é n = 1.
guided, [n]: o laço é dividido em pedaços de n itens sequênciais. Cada thread recebe um pedaço até que todos os pedaços sejam distribuídos. No entanto, a distribuição dos pedaços entre os threads é feita de forma guiada, ou seja, cada thread pode pegar um novo pedaço assim que terminar o anterior. No entanto, o tamanho do próximo pedaço a ser pego diminui a cada iteração. Por padrão, o primeiro pedaço tem tamanho n = ceiling(num_of_iterations/num_of_threads) e os próximos têm camanho ceiling(num_of_iterations_left/num_of_threads).
auto: a divisão entre as threads é delegada ao compilar e ao sistema.
Uma redução é uma operação que combina os resultados de várias threads em um único resultado. Por exemplo, a soma dos elementos de um vetor é uma operação de redução. A diretiva omp reduction
pode ser usada para especificar uma operação de redução em um laço.
Por exemplo, o seguinte código implementa um método para computar o produto interno entre dois vetores de elementos.
Na linha 9 do código, a diretiva omp parallel for reduction(+:result) indica que o laço for deve ser paralelizado e que a variável result deve ser reduzida. A operação de redução é especificada entre parênteses. Neste caso, a operação de redução é a soma. A variável result é inicializada em cada thread e, ao final do laço, os resultados parciais são somados para obter o resultado final. Reduções com as operações *, /, - também são suportadas.
Teste a eficiência do Código 5 para diferentes tamanhos de matrizes. O que ocorre quando aumenta? E quando aumenta?
Teste a eficiência do Código LABEL:cap_mp:cod:matVec para diferentes tipos de distribuição de laços pela cláusula schedule. Qual é a mais eficiente em seu computador? Porquê?
Desenvolva um método com OpenMP/C++ para computar a integral de uma função em um intervalo pela regra composta de Simpson22endnote: 2Thomas Simpson, 1710 - 1761, matemático britânico. Fonte: Wikipédia: Thomas Simpson. com um número arbitrário de subintervalos . Use a diretiva omp parallel for
para paralelizar os laços de redução.
Aproveito para agradecer a todas/os que de forma assídua ou esporádica contribuem enviando correções, sugestões e críticas!
Este texto é disponibilizado nos termos da Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional. Ícones e elementos gráficos podem estar sujeitos a condições adicionais.