Visual Basic em Português

Página pessoal de Jorge Paulino sobre o Visual Basic (VB.NET, ASP.NET, VB6, VBA) e algumas noticias de tecnologia

VS2010 RC1: Task Parallel Library – Parallel.Invoke()

Nos artigos anteriores sobre a Task Parallel Library (TPL) foram referidos os métodos Parallel.For e Parallel.ForEach que servem essencialmente para criar ciclos que podem correr em paralelo. Este método, o Parallel.Invoke, serve para executar processos que decorrem eventualmente em paralelo.

Quando os processos são invocados, são separados nos diversos núcleos do processador e o código só avança quando todos tiverem terminado.

Eis um exemplo do funcionamento:

Imports System.Threading
Imports System.Threading.Tasks

Module Module1

  Private Sub task1()
    For x As Integer = 0 To 50
      Console.WriteLine("Task1 - {0}", x.ToString())
      System.Threading.Thread.SpinWait(50000000)
    Next
  End Sub

  Private Sub task2()
    For x As Integer = 0 To 50
      Console.WriteLine("Task2 - {0}", x.ToString())
      System.Threading.Thread.SpinWait(50000000)
    Next
  End Sub

  Sub Main()

    ' Chama as diversas acções (incluindo uma Lambda)
    Dim actions() As Action = {AddressOf task1, AddressOf task2,
                                 Sub()

                                   ' Usando uma Lambda Expression
                                   For x As Integer = 0 To 50
                                     Console.WriteLine("Task3 - {0}", x.ToString())
                                     System.Threading.Thread.SpinWait(50000000)
                                   Next

                                 End Sub}

    Parallel.Invoke(actions)

    Console.WriteLine("Acções completas!")

  End Sub

End Module

Executando o mesmo, mas sequencialmente (onde o tempo de execução é significativamente superior):

Imports System.Threading
Imports System.Threading.Tasks

Module Module1

  Private Sub task1()
    For x As Integer = 0 To 50
      Console.WriteLine("Task1 - {0}", x.ToString())
      System.Threading.Thread.SpinWait(50000000)
    Next
  End Sub

  Private Sub task2()
    For x As Integer = 0 To 50
      Console.WriteLine("Task2 - {0}", x.ToString())
      System.Threading.Thread.SpinWait(50000000)
    Next
  End Sub

  Sub Main()

    task1()
    task2()

    For x As Integer = 0 To 50
      Console.WriteLine("Task3 - {0}", x.ToString())
      System.Threading.Thread.SpinWait(50000000)
    Next

  End Sub

End Module

E é o terceiro e último evento da classe Parallel. Como se pode ver nos exemplos apresentados(For, ForEach e Invoke), são muito simples de utilizar e vai de certeza ajudar a melhorar o desempenho das aplicações.


VS2010 RC1: Task Parallel Library – Parallel.ForEach()

Este método executa um ciclo semelhante à instrução For Each, mas que possibilita a execução em paralelo. É muito semelhante ao exemplo do artigo anterior, mas difere do Parallel.For() pois é usado quando os dados são colecções ou arrays.

Eis um exemplo da sua implementação/utilização:

Imports System.Threading
Imports System.Threading.Tasks

Module Module1

  Sub Main()
    Dim result1, result2 As Long
    Dim values = Enumerable.Range(0, 49)

    Dim sw As New Stopwatch
    sw.Start()

    ' ------------------------------------------------
    ' Ciclo For Each
    ' ------------------------------------------------
    For Each value As Integer In values
      Console.WriteLine("Value:{0} GUI:{1}", value.ToString(), Guid.NewGuid())
      Thread.SpinWait(50000000)
    Next

    result1 = sw.ElapsedMilliseconds

    sw.Restart() ' <- novo método no Visual Studio 2010

    ' ------------------------------------------------
    ' Ciclo Parallel.ForEach
    ' ------------------------------------------------
    Parallel.ForEach(values, Sub(value)
                               Console.WriteLine("Value:{0} GUI:{1}",
                                                 value.ToString(),
                                                 Guid.NewGuid())
                               Thread.SpinWait(50000000)
                             End Sub)

    result2 = sw.ElapsedMilliseconds
    sw.Stop()

    Console.WriteLine("Tempo de execução 'For Each' {0} ms", result1)
    Console.WriteLine("Tempo de execução 'Parallel.ForEach' {0} ms", result2)
    Console.ReadKey(True)

  End Sub

End Module

E os resultados são uma vez mais significativos:

É mais um ciclo disponível da Task Parallel Library (TPL) – Parallel Extensions, que quando bem aplicado pode melhorar bastante o desempenho da aplicação.


VS2010 RC1: Task Parallel Library – Parallel.For()

Data parallelism refere-se a situações em que a mesma operação é realizada simultaneamente (ou seja em paralelo) em elementos de uma colecção ou array. A classe System.Threading.Tasks.Parallel, do namespace System.Threading.Tasks, fornece um conjunto de métodos que permitem a execução de ciclos. Com a utilização do Parallel.For, Parallel.ForEach e Parallel.Invoke, incluindo inúmeros overloads disponíveis, é possível melhorar o desempenho das aplicações.

O método Parallel.For executa um ciclo que pode correr em paralelo. O sintaxe é o seguinte: Parallel.For(Int32, Int32, Action(Of Int32))

Executando um ciclo simples ou “normal”:

      Dim sw As New Stopwatch()
      sw.Start()

      ' Executa o método For ... Next
      For x As Integer = 0 To 500
        Console.WriteLine("Thread ID={0} - x={1}",
                          Thread.CurrentThread.ManagedThreadId, x)
        Thread.Sleep(100)
      Next x

      Console.WriteLine("Tempo de execução: {0} ms", sw.ElapsedMilliseconds)
      sw.Stop()

Como é possível ver nos seguintes resultados, o tempo de execução é longo, e o valor da variável x que é mostrado é continuo. A thread é também sempre a mesma (neste caso 9).

Para realizarmos o mesmo ciclo, mas desta vez recorrendo às Parallel Extensions, e melhorando desta forma o desempenho, podemos usar o método Parallel.For. Neste exemplo é usado Lambda para mostrar os resultados:

      Dim sw As New Stopwatch()
      sw.Start()

      ' Executa o método Parallel.For()
      Parallel.For(0, 500, Sub(x)
                             Console.WriteLine("Thread ID={0} - x={1}",
                                               Thread.CurrentThread.ManagedThreadId, x)
                             Thread.Sleep(100)
                           End Sub)

      Console.WriteLine("Tempo de execução: {0} ms", sw.ElapsedMilliseconds)
      sw.Stop()

Como é possível nos seguintes resultado, o tempo de execução é inferior, sendo usadas diversas threads, que são distribuídas e executadas nos diversos núcleos do processador. Isto justifica também porque o valor de x não é mostrado de forma continua.

Os resultados falam por si, ma é importante lembrar, que num exemplo simples sem que existam tarefas complexas (que possam demorar algum tempo a executar), a utilização dos métodos Parallel.For ou Parallel.ForEach é mais lento do que um ciclo simples (For … Next ou For Each … Next). Isto porque em cada ciclo é criada um Delegate (System.Action) que irá ser chamado e isso irá aumentar o tempo de execução.

É por isto muito importante definir bem onde utilizar, desenhar a aplicação de modo a poder incluir a utilização de Parallel Extensions, neste caso as Task Parallel Library (TPL), e testar sempre (analisando os resultados)!


VS2010 RC1: Parallel Extensions

A evolução dos CPU’s deixou, nos últimos anos, de estar relacionada com a velocidade do CPU, mas sim com o número de núcleos que este tem. Estes núcleos (cores) permitem executar diversos processos em simultâneo, melhorando a utilização e performance das aplicações, sendo para isso necessário que elas estejam desenhadas e preparadas para o fazer.

O Visual Studio 2010 e a .NET Framework 4.0 trazem um conjunto de melhorias com o objectivo de tirar partido do hardware, nomeadamente melhorias no namespace System.Theading, a introdução das Parallel Extensions, que são um conjunto de classes que permitem implementar a programação de tarefas em paralelo e a Unified Cancellation Model, que é, de uma forma sucinta, uma simplificação do processo de cancelamento de diversas threads usando um só comando.

São também novidade duas ferramentas de diagnóstico: Parallel Stacks Window  e Parallel Tasks Window.

Sobre as Parallel Extensions, as principais novidades são:

O Visual Studio 2010 e a plataforma .NET Framework 4.0 vêm assim melhorar e simplificar o o processo de criação de threads, substituindo de certa forma, com as Parallel Extensions, a classe System.Theading.Thead (embora possível de utilizar).




Microsoft Office Especialist

Membro da Comunidade
Experts-Exchange


Administ. da Comunidade
Portugal-a-Programar



Twitter

Artigos no CodeProject

Artigos no CodeProject

Subscrever Novidades

Endereço de Email:

Delivered by FeedBurner

Seguidores

Histórico