É uma função sem braçadeira paralelizável?

votos
3

considerando o código abaixo, podemos considerá-lo paralelas mesmo se não há laços?

#include <omp.h>

int main(void) {
  #pragma omp parallel
  {
    int a = 1;
    a = 0;
  }
  return 0;
}
Publicado 27/11/2018 em 17:58
fonte usuário
Em outras línguas...                            


1 respostas

votos
6

Resposta direta:

Sim, aqui, a seção de seu código,

int a = 1;
a = 0;

É executado em paralelo, os tempos de P, onde P é o número de núcleos em sua máquina.

Por exemplo, em uma máquina de quatro núcleos, o código a seguir (com as importações relevantes),

int main(void) {
    #pragma omp parallel
    {
        printf("Thread number %d", omp_get_thread_num());
    }
    return 0;
}

saída seria:

Thread number 0
Thread number 1
Thread number 2
Thread number 3

Note que quando executado em paralelo, não há nenhuma garantia sobre a ordem de saída, para que a saída poderia muito provavelmente ser algo como:

Thread number 1
Thread number 2
Thread number 0
Thread number 3

Além disso, se você queria para especificar o número de threads utilizados na região paralelo, em vez de #pragma omp parallelvocê poderia escrever, #pragma omp parallel num_threads(4).


Além disso Explicação:

Se você ainda está confuso, ele pode ser útil para entender melhor a diferença entre paralelo para loops e regiões de código paralelas.

#pragma omp paralleldiz ao compilador que o bloco de código a seguir podem ser executadas em paralelo. Ela garante que todo o código dentro da região paralela terá execução acabado antes de continuar a código subseqüente.

No seguinte (brinquedo) exemplo, o programador é garantido que, após a região paralelo, a matriz terá todas as entradas definidas para zero.

int *arr = malloc(sizeof(int) * 128); 
const int P = omp_get_max_threads();

#pragma omp parallel num_threads(P)
{
    int local_start = omp_get_thread_num();
    int local_end = local_start + (100 / P);
    for (int i = local_start; i < local_end; ++i) {
        arr[i] = 0;
    }

}
// any code from here onward is guaranteed that arr contains all zeros!

Ignorando as diferenças de escalonamento, essa tarefa pode equivalentemente ser realizada utilizando um paralelo para o laço como se segue:

int *arr = malloc(sizeof(int) * 128); 
const int P = omp_get_max_threads();

#pragma omp parallel num_threads(P) for
for (int i = 0; i < 128; ++i) {
    arr[i] = 0;
}
// any code from here onward is guaranteed that arr contains all zeros!

Essencialmente, #pragma omp parallelpermite descrever regiões de código que pode executar em paralelo - isso pode ser muito mais flexível do que um paralelo para loop. Em contraste, #pragma omp parallel fordeve geralmente ser usadas para paralelizar loops com iterações independentes.

I pode ainda elaborar sobre as diferenças de desempenho, se você gostaria.

Respondeu 27/11/2018 em 18:13
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more