Getting deeper with TPL & async (Spanish version)

  • Published on
    12-Nov-2014

  • View
    54

  • Download
    0

Embed Size (px)

DESCRIPTION

Presentation about the Task Parallel Library and the new async paradigm in .NET Framework.

Transcript

<ul><li> 1. Irn Reyes Fleitas</li></ul><p> 2. Temas: TPL Paralelizacin de cdigo imperativo. Programacin Paralela con tareas(Task). Colecciones de Concurrencia y Pipelines. Estructuras para la coordinacin de los datos. Async 3. Evolucin C# 4. Paralelizacin de cdigo imperativoParallel.Invoke, Parallel Loops, Cancelando, Excepciones, Particionando . Programacin Paralela con tareas(Task)Task, TimeOuts, Cancelando, Excepciones, Retornando valores. Colecciones de Concurrencia y PipelinesConcurrentQueue, ConcurrentStack, ConcurrentBag, BlockingCollection,ConcurrentDictionary. 5. Parallel Class( System.Threading.Tasks )Parallel.ForParallel.ForEachParallel.Invoke 6. Parallel.InvokeLa manera ms simple de paralelizar varios mtodos.Sintaxis:Invoke( Action [] )Invoke( ParallelOptions, Action [] )No se tiene garanta de orden.No retorna hasta que cadainvocacin no hay finalizado.GoToRiver GoToPark GoToZoo GoToPlainAreaParallel.Invoke(Walk.GoToPark, Walk.GoToRiver, Walk.GoToZoo, Walk.GoToPlainArea);Parallel.Invoke(() =&gt; Walk.GoToPark("Santiago"),Walk.GoToRiver,delegate() { Walk.GoToZoo("26st"); },Walk.GoToPlainArea);PatrnFork/Join 7. 3 posibles escenarios de paralelismo EscenarioIdealEjemplo hipottico con una arquitectura con4 ncleos lgicos.1era ejecucinGoToZooGoToRiverGoToParkGoToPlainArea2da ejecucinGoToParkGoToRiverGoToPlainAreaGoToZoo3era ejecucinGoToZooGoToPlainAreaGoToRiverGoToPark 8. Ventajas y Desventajas1. Es un mtodo muy simple de lograr paralelismo sin tareas, ni hilos.1. Mtodos con notables diferencias en cuanto al tiempo de ejecucin.2. Cada llamada crea una sobrecarga antes de correr los mtodos.3. Como todo cdigo en paralelo, esta expuesto a existencias deinterdependencia e incontrolables interacciones.4. No tiene garanta de orden. 9. Anlisis de tiempo con respecto al secuencialWalk.GoToPark();Walk.GoToRiver();Walk.GoToZoo();Walk.GoToPlainArea();Ejemplo hipottico (figuras)con unaarquitectura con 4 ncleos lgicos ymediciones con 2 ncleos lgicosParallel.Invoke(Walk.GoToPark, Walk.GoToRiver, Walk.GoToZoo, Walk.GoToPlainArea); 10. Parallel.ForVersin paralelizada del clsico for.Sintaxis:For( Int32, Int32, Action )For( Int32, Int32, Action )List data = new List(){"Estamos","paralelizando","el","for","y","el","foreach"};Tradicional Paralelizadofor (int i = 0; i &lt; data.Count; i++){Console.Write(i);}Parallel.For(0, data.Count, x =&gt;{Console.Write(x);});No tiene por que cumplirse el orden.Tener en cuenta si los elementosestan relacionados entre si.Desde LowerBound a UpperBound.El primer parmetro es inclusivo,el segundo exclusivo.Load-BalancePequeos bodies. 11. Anlisis de tiempo con respecto al secuencial(RayTracing)void Render(Scene scene, Color[,] rgb){for (int y = 0; y &lt; screenHeight; y++){for (int x = 0; x &lt; screenWidth; x++)rgb[x,y] = TraceRay(new Ray(scene,x,y));}}void Render(Scene scene, Color[,] rgb){Parallel.For(0, screenHeight, delegate(int y){for (int x = 0; x &lt; screenWidth; x++)rgb[x,y] = TraceRay(new Ray(scene,x,y));});}Ocho ncleos y 350 x 350Secuencial: 1.7 fpsParalelo : 12 fpsDos ncleos y 350 x 350Secuencial: 1.0 fpsParalelo : 2.0 fpsDos ncleos y 578 x 485Secuencial: 0.5 fpsParalelo : 1.0 fps 12. Anlisis de tiempo con respecto al secuencial(Primos)List primes = new List();int cotaSup = 50000;for (int i = 2; i &lt; cotaSup; i++){if (isPrime(i))primes.Add(i);}Parallel.For(2, cotaSup, (i) =&gt;{if (isPrime(i))primes.Add(i);});0.5 segundos0.2 segundos0.5/0.2 = 2.5xEjemplo hipottico (figuras)con unaarquitectura con 4 ncleos lgicos ymediciones con 2 ncleos lgicos 13. F#let sentences = [|"Estamos"; "paralelizando"; "el"; "for"; "y"; "el";"foreach"|]for index=0 to sentences.Length doprintfn "%d" indexprintfn ""let accion indice =printfn "%d" indiceParallel.For(0,sentences.Length, new Action(accion))Console.ReadKey(); 14. Parallel.ForEachVersin paralelizada del clsico foreach.Sintaxis:ForEach ( IEnumerable , Action )ForEach ( IEnumerable , Action )List data = new List(){"Estamos","paralelizando","el","for","y","el","foreach"};foreach (var items in data){Console.Write(items + " ");}Tradicional ParalelizadoParallel.ForEach(data, x =&gt;{Console.Write(x + " ");}); 15. Anlisis de tiempo con respecto al secuencialEjemplo hipottico (figuras)con unaarquitectura con 4 ncleos lgicos ymediciones con 2 ncleos lgicosforeach (var i in inputData){if (isPrime(i))resultData[indice] = i;indice++;}28 segundos14 segundosvar op = Partitioner.Create(inputData);Parallel.ForEach(op, (item, loopState, index) =&gt;{28/14 = 2xif (isPrime(item))resultData[index] = item;}); 16. Como paramos los ciclos?(Cancelando)ParallelLoopState ParallelLoopResultParallelLoopResult loopResult1 = Parallel.For(0, 10, (x, state) =&gt;{if (x &lt; 5)Console.WriteLine(x);elsestate.Stop();});ParallelLoopResult loopResult2 = Parallel.ForEach(data, (x, state) =&gt;{if (!x.Equals("y"))Console.WriteLine(x);elsestate.Break();});Console.WriteLine(loopResult1.LowestBreakIteration);Console.WriteLine(loopResult1.IsCompleted);Console.WriteLine(loopResult2.LowestBreakIteration);Console.WriteLine(loopResult2.IsCompleted); 17. Manejo de ExcepcionesAggregateExceptionFormato:try{..........}catch (AggregateException aggEx){foreach (Exception ex in aggEx.InnerExceptions){Console.WriteLine(string.Format("Caught exception '{0}'",ex.Message));}} 18. Manejo de ExcepcionesEjemplo:try{ParallelLoopResult loopResult = Parallel.For(0, 10, (x, state) =&gt;{if (x &lt; 5)Console.WriteLine(x);else{var ex = "Excepcin en el ndice " + x;throw new InvalidDataException(ex);}});Console.WriteLine("Ciclo for completado: {0}", loopResult.IsCompleted);}catch (AggregateException aggEx){foreach (var innerException in aggEx.InnerExceptions){//Pueden haber 2 excepciones a causa del paralelismo.Console.WriteLine("Excepcion capturada: " + innerException.Message);}} 19. ParallelOptionsParallelOptions.MaxDegreeOfParallelismParallelOptions.TaskSchedulerParallelOptions.CancellationTokenSe utilizan en losmtodos de Parallel.var source = Enumerable.Range(8, 2000).ToArray();double[] result = new double[source.Length];ParallelOptions parallelOptions = new ParallelOptions();parallelOptions.MaxDegreeOfParallelism = Environment.ProcessorCount*2; //EjemploParallel.ForEach(Partitioner.Create(8, source.Length),parallelOptions, range =&gt;{for (int i = range.Item1; i &lt; range.Item2; i++)result[i] = source[i]*Math.E;}); 20. ParticionandoParticin por rangos Particin por bloquesPartitioner.Create(1,40)Parallel.ForEach(Partitioner.Create(10, 200), range =&gt;{Console.WriteLine("{0},{1}",range.Item1,range.Item2);for (int i = range.Item1; i &lt; range.Item2; i++){data[i] = data[i]*i;}});Optimizando el particionado segn el nmero de ncleos.Partitioner.Create(1,40, ((numeroDeElementos/numeroDeNucleos)+1))System.Environment.ProcessorCountSintaxis:Create ( IEnumerable )Create ( Int32, Int32)Create ( Int32, Int32, Int32) 21. Paralelizacin de cdigo imperativoParallel.Invoke, Parallel Loops, Cancelando, Excepciones, Particionando . Programacin Paralela con tareas(Task)Task, TimeOuts, Cancelando, Excepciones, Retornando valores. Parallel Linq (PLinq)Operadores, Cancelando, Agregaciones, Excepciones. Colecciones de Concurrencia y PipelinesConcurrentQueue, ConcurrentStack, ConcurrentBag, BlockingCollection,ConcurrentDictionary. 22. Task 23. Task - Scheduling 24. Ciclo de vida y estado de una tareaEnumTaskStatusMiembros:CreatedWaitingForActivationWaitingToRunRunningWaitingForChildrenToCompleteRanToCompletionCanceledFaulted 25. Invocando TareasGenerateSomething GenerateNothingParallel.Invoke(GenerateSomething,() =&gt; GenerateNothing());//Los mtodos no estn corriendo todava, pero las tareasestn listas para empezar.//El estado para ambas tareas es TaskStatus.Created.var task1 = new Task(GenerateSomething);var task2 = new Task(() =&gt; GenerateNothing());task1.Start();task2.Start();Task.WaitAll(task1, task2);var task1 = Task.Factory.StartNew(() =&gt; GenerateNothing()); 26. TimeOutsvar task1 = new Task(GenerateSomethingTimeOut);var task2 = new Task(() =&gt; GenerateNothing());task1.Start();task2.Start();if(!Task.WaitAll(new Task[]{task1,task2},300)){Console.WriteLine("GenerateSomething y GenerateNothing han tardado ms de300ms");}if(!task1.Wait(300)){Console.WriteLine("GenerateSomething ha tardado ms de 300ms");} 27. Manejando excepciones con las Taskstatic void GenerateSomethingCancel(CancellationToken cancellationToken){cancellationToken.ThrowIfCancellationRequested();Console.WriteLine("GenerateSomething");Thread.Sleep(3000);if (sw.Elapsed.Seconds &gt; 1)throw new TimeoutException("La tarea se demor mas de 1 segundos");cancellationToken.ThrowIfCancellationRequested();}try{// Espera por que todas las tareas finalicen en menos de 3 segundosif (!Task.WaitAll(new Task[] { task1, task2 }, 3000)){Console.WriteLine("GenerateSomething y GenerateNothing han tardado ms de 300ms en terminar");Console.WriteLine(task1.Status.ToString());Console.WriteLine(task2.Status.ToString());}}catch (AggregateException ex){foreach (Exception innerEx in ex.InnerExceptions){Console.WriteLine(innerEx.ToString());}} 28. Retornando valores desde las tareasstatic List GenerateSomethingReturn(){Console.WriteLine("GenerateSomething");Thread.Sleep(3000);return new List{"Estoy","retornando","una","lista","de","strings."};}var task1 = Task.Factory.StartNew(() =&gt; GenerateSomethingReturn());try{task1.Wait();}catch (AggregateException ex){foreach (Exception innerEx in ex.InnerExceptions){Console.WriteLine(innerEx.ToString());}}var task2 = Task.Factory.StartNew(() =&gt;{foreach (var result in task1.Result){Console.WriteLine(result);}}); 29. Cancelando Tareas usando TokensCancellationToken cancellationTokenCancellationTokenSourceSe pasa como parmetroControla la cancelacin desde el mtodo principalstatic void GenerateSomethingCancel(CancellationToken cancellationToken){cancellationToken.ThrowIfCancellationRequested();Console.WriteLine("GenerateSomething");Thread.Sleep(3000);cancellationToken.ThrowIfCancellationRequested();}var cts = new CancellationTokenSource();var ct = cts.Token;var task1 = Task.Factory.StartNew(() =&gt; GenerateNothingCancel(ct),ct);cts.Cancel();if (task1.IsCanceled){Console.WriteLine("La Tarea GenerateSomethingCancel que estaba en ejecucion fue cancelada");} 30. TaskCreationOptionsOptimizando el cdigoTaskCreationOptions.AttachedToParentTaskCreationOptions.NoneTaskCreationOptions.LongRunningTaskCreationOptions.PreferFairnessvar task2 = Task.Factory.StartNew(() =&gt;Ayudar al Scheduler{foreach (var result in task1.Result){Console.WriteLine(result);}},TaskCreationOptions.PreferFairness); 31. Concatenando mltiples tareas usando Continuacintry{var task1 = Task.Factory.StartNew(() =&gt; GenerateSomethingCancelReturn(ct), ct);var task2 = task1.ContinueWith(t =&gt;{foreach (var result in t.Result){Console.WriteLine(result);}});task1.Wait();}catch (AggregateException ex){foreach (Exception innerEx in ex.InnerExceptions){Console.WriteLine(innerEx.ToString());}}var task2 = Task.Factory.StartNew(() =&gt;{foreach (var result in task1.Result){Console.WriteLine(result);}}); 32. var f = Task.Factory;var build1 = f.StartNew(() =&gt; Build(project1));var build2 = f.StartNew(() =&gt; Build(project2));var build3 = f.StartNew(() =&gt; Build(project3));var build4 = build1.ContinueWith(() =&gt; Build(project4));var build5 = f.ContinueWhenAll(new[] { build1, build2, build3 }, () =&gt; Build(project5));var build6 = f.ContinueWhenAll(new[] { build3, build4 }, () =&gt; Build(project6));var build7 = f.ContinueWhenAll(new[] { build5, build6 }, () =&gt; Build(project7));var build8 = build5.ContinueWith(() =&gt; Build(project8));Task.WaitAll(build1, build2, build3, build4, build5, build6, build7, build8); 33. Mezclando paralelismo y cdigo secuencial con Continuacin 34. TaskContinuationOptionsTaskContinuationOptions.AttachedToParentTaskContinuationOptions.ExecuteSynchronouslyTaskContinuationOptions.LongRunningTaskContinuationOptions.PreferFairnessTaskContinuationOptions.NoneTaskContinuationOptions.NotOnCanceledTaskContinuationOptions.NotOnFaultedTaskContinuationOptions.NotOnRanToCompletionTaskContinuationOptions.OnlyOnCanceledTaskContinuationOptions.OnlyOnFaultedTaskContinuationOptions.OnlyOnRanToCompletionvar task2 = task1.ContinueWith(t =&gt;{foreach (var result in t.Result){Console.WriteLine(result);}},TaskContinuationOptions.None);Especificando el comportamientode la prxima tareaCondicionando la prxima tarea 35. Anlisis de tiempo con respecto a los ThreadEjemplo hipottico con una arquitecturacon 2 ncleos lgicos.64 Threads versus 64 Tasks1. Los primos hasta el 50 : Thread 0.9 segundos.Tasks 0.2 segundos.2. Los primos hasta el 500 : Thread 2 segundos.Tasks 1 segundo.3. Los primos hasta el 5000 : Thread 15 segundos.Tasks 13 segundos.4. Los primos hasta el 50000: Thread 116 segundos.Tasks 104 segundos. 36. Paralelizacin de cdigo imperativoParallel.Invoke, Parallel Loops, Cancelando, Excepciones, Particionando . Programacin Paralela con tareas(Task)Task, TimeOuts, Cancelando, Excepciones, Retornando valores. Colecciones de Concurrencia y PipelinesConcurrentQueue, ConcurrentStack, ConcurrentBag, BlockingCollection,ConcurrentDictionary. 37. var data = new List();Parallel.ForEach(Partitioner.Create(0, 200), range =&gt;{for (int i = range.Item1; i &lt; range.Item2; i++)lock (data)data.Add(i);});data.ForEach(x =&gt; Console.Write(x + " "));Solucin 38. Colecciones Thread-Unsafe:System.CollectionsSystem.Collections.GenericColecciones Thread-Safe:System.collections.ConcurrentConcurrentQueueConcurrentStackConcurrentBagConcurrentDictionaryBlockingCollectionIProducerConsumerCollection 39. Colecciones de concurrencia ideales paraescenarios productor-consumidor. 40. ConcurrentQueueLock-FreeMtodos Importantes:EnqueueTryDequeueTryPeek 41. ConcurrentQueue-Esta coleccion es completamente libre de lock (lock-free)-Usa compare and swap (CAS)-Cuando falla una operacion CAS se pone en estado decontencion. 42. ConcurrentQueue-Produce (over-head).-Mejora el rendimiento de la cola y otras coleccionesthread-unsafe, en determinados escenarios.-Nos facilita el trabajo con la concurrencia. 43. ConcurrentQueueCaracteristicas importantes:concurrentQueue.Enqueue(item);if (concurrentQueue.TryPeek(out item)){DoSomething(item);}if (concurrentQueue.TryDequeue(out item)){DoSomething(item);} 44. ConcurrentStackMtodos Importantes:PushTryPopTryPeek 45. ConcurrentStackOtros Mtodos:PushRangePopRange 46. ConcurrentStack-Similar a la coleccion ConcurrentQueue.-Es una coleccion LIFO.-Atomicidad en los metodos PushRange y PopRange reduce la cantidadde insersiones y extracciones concurrentes en la coleccion. 47. ConcurrentStackCaracteristicas importantes:concurrentStack.Push(item);if (concurrentStack.TryPeek(out item)){DoSomething(item);}if (concurrentStack.TryPop(out item)){DoSomething(item);} 48. ConcurrentStackCaracteristicas importantes:Parallel.ForEach(Partitioner.Create(0, partCount), p =&gt;{concurrentStack.PushRange(numberArray, p.Item1, p.Item2 - p.Item1);}); 49. ConcurrentStackSintaxis:count = s.TryPopRange(numberArray, 0, numberArray.Length);count = s.TryPopRange(numbe...</p>