Article image

MC

Matheus Caldas24/02/2024 15:31
Compartilhe

Entendo processamento paralelo no C# com o método Parallel.ForEach()

    Com a evolução dos processadores, foi notado que apesar de ser possível aumentar a quantidade de informação processada de uma vez, diminuir o tempo necessário nesse processo é outra história, sendo necessária outra abordagem para criar processadores mais poderosos e rápidos e a alternativa foi o processamento paralelo ao dividir a CPU em múltiplos núcleos de igual capacidade. A classe Parallel do C# está no pacote de Threading que foca na utilização de múltiplos núcleos e é examente o que o método da vez faz. O método Parallel.ForEach basicamente recebe um vetor e um metódo que será executado em cada elemento do vetor, a diferença do convencional é que isso é feito em um núcleo diferente do principal.

    O que é o processamento paralelo

    Como o nome sugere, o processamento paralelo caracteriza uma máquina de executar mais de um processo simultaneamente, no caso dos nossos computadores, ele é implementado através de vários "núcleos" iguais dentro do processador. Quanto mais núcleos uma CPU tiver mais processos ele poderá executar simultaneamente.

    Em uma comparação rápida, um i9 de 14° geração possui 24 núcleos enquanto um i9 de 11° geração possui apenas 8, nesse exemplo o processador de 14° geração pode executar 3 vezes mais processos simultâneos do que o de 11°.

    Fonte: Intel - Processadores i9

    Como C# lida com o paralelismo

    Segundo a própria Microsoft, a .NET desde da sua versão Framework 4 disponibiliza um conjunto de bibliotecas de classes e ferramentas de diagnósticos retirando a necessidade de manipular os núcleos em linguagens de baixo nível e possiblitando o desenvolvimento em linguagem natural.

    Fonte: Microsoft Learn - Programação Paralela

    Como funciona o paralelismo na prática

    Uma classes desponíveis para utilizar do paralelismo é a classe estática Parallel que contém um conjunto de métodos para executar _regiões de código_ e _loops._ Para entender seu funcionamento eu irei usar o método ForEach().

    O método ForEach() é um método públic e estático que utiliza basicamente de um IEnumerable e de uma Action para realizar um loop foreach em outro núcleo sincronizado ao principal. Para exemplificar o funcionamento desse método vou criar a classe Num para segurar um inteiro que será alterado durante o loop.

    public class Num {
      public int value;
     
      public Num(int value) {
          this.value = value;
      }
      
      public override string ToString() {
          return value.ToString();
      }	
    }
    

    Agora, no método principal vou criar um vetor de 50 números de 1 até 50.

    public static void Main()
    {
      Num[] numbers = new Num[500]; // Vetor
      for (int i=0; i<500; i++) {
          numbers[i] = new Num(i + 1);
      }
    
      // Imprimindo todos os valores do vetor
    Console.WriteLine(String.Join<Num>(", ", numbers)); 
    // Saída: 1, 2, 3, 4, 5, ...
    
    // Restante do código    
    }     
    

    Com o vetor podemos elevar todos os valores por 2 e obter o quadrado deles através do método Prallel.ForEach(). O método funciona cria um loop igual à palavra-chave foreach.

    public static void Main()
    {
      // Restante do código
    
      Parallel.ForEach<Num>(numbers, n => {
          n.value *= n.value;
      });
      Console.WriteLine(String.Join<Num>(", ", numbers));
    // Saída: 1, 4, 9, 16, 25, ...
    }
    

    Fonte: Microsoft Learn - Classe Parallel

    Compartilhe
    Comentários (0)