SlideShare uma empresa Scribd logo
1 de 69
Parallel Computing with .NET 4.0
Sacando partido al multi-core
Lluís Franco - AndorraDotNet
Agenda
1. Programación paralela ¿Queéloqueé?
2. Un poco de historia y algunos conceptos.
3. ¿Multithreading versus Parallel?
4. Paralelismo en .NET 4.0 (PLINQ, Parallel, Task)
5. Demos…
6. Demos……
7. Y si… más demos 
2
Let’s play!
Parallel Computing with .NET 4.0
3
1 - ¿Y eso queéloqueé?
¿Esto?
4
1 - ¿Y eso queéloqueé?
¿Acaso esto?
5
1 - ¿Y eso queéloqueé?
Wikipedia dixit:
“La computación paralela es una técnica de programación en la que muchas
instrucciones se ejecutan simultáneamente. Se basa en el principio de que los
problemas grandes se pueden dividir en partes más pequeñas que pueden resolverse
de forma concurrente”.
“Existen varios tipos de computación paralela: paralelismo a nivel de bit, paralelismo a
nivel de instrucción, paralelismo de datos y paralelismo de tareas”.
“Durante muchos años, la computación paralela se ha aplicado en la computación de
altas prestaciones, pero el interés en ella ha aumentado en los últimos años debido a
las restricciones físicas que impiden el escalado en frecuencia”.
6
1 - ¿Y eso queéloqueé?
La Ley de Moore expresa
que aproximadamente
cada 18 meses (*) se
duplica el número de
transistores en un circuito
integrado. Se trata de una
ley empírica, formulada
por el co-fundador de Intel,
Gordon E. Moore el 19 de
abril de 1965, cuyo
cumplimiento se ha podido
constatar hasta hoy.
Ley de Moore:
(*) 2 años (1975).
7
1 - ¿Y eso queéloqueé?
• La ley de Moore ha muerto:
– Tecnología actual 32 nanómetros
– Límite 18 nanómetros (cambios)
– Se alcanzará aprox. en 2014
• Solución:
– Más núcleos
– Computación en paralelo
– INTEL / AMD / NVIDIA (CUDA)
«La materia presenta
efectos cuánticos que
harían necesaria una
tecnología diferente
para seguir realizando
cálculos a ese nivel».
Stephen Hawking
8
2 – Un poco de historia
¿Alguien recuerda los CRAY?
1976: Es uno de los supercomputadores más
conocidos y exitosos de la historia, y de los más
potentes en su época
9
2 – Un poco de historia
¿Y a Deep Blue?
1997: El primer ordenador en batir
a un gran maestro (Garry Kasparov)
10
2 – Algunos conceptos
Procesos & Threads en un sistema operativo
11
Un proceso proporciona los recursos
necesarios para ejecutar un programa.
Contiene un espacio de memoria virtual,
código ejecutable, un contexto de
seguridad, un identificador de proceso
único, variables de entorno, y al menos
un thread de ejecución.
Cada proceso se inicia con un único
thread, a menudo llamado thread
principal, pero puede crear threads
adicionales.
2 – Algunos conceptos
Procesos & Threads en un sistema operativo
12
Un thread es la entidad dentro de un
proceso que realmente ejecuta el código.
Todos los threads de un proceso
comparten los recursos y memoria virtual.
Además, cada thread mantiene
controladores de excepciones, una
prioridad de programación,
almacenamiento local, y un identificador
de thread único.
A más threads, más tiempo de CPU.
Lógico, no?
3 - ¿Multithreading vs. Parallism?
• Tipos de Multitarea:
– Cooperativa o No Preemptiva (Windows anteriores a
Win95/WinNT y MacOS): Cada proceso se ocupa de pasar
el control al siguiente proceso. Un mal diseño de una
aplicación y CATACRACK!
– Preferente o Preemptiva (Windows Win95 y superiores, el
resto de S.O. modernos): El sistema operativo es el
encargado de ceder un tiempo a cada thread de cada
proceso (time slice). Un mal diseño de una aplicación no
implica el derrumbe del S.O. ya que se ejecutan en modo
user.
13
3 - ¿Multithreading vs. Parallism?
• Multithreading:
– Técnica que consiste en manejar varios threads en una aplicación:
– Permite realizar tareas asíncronas al ‘mismo tiempo’ (aunque
realmente no es así).
– No es trivial (más complejidad, depuración, acceso prohibido a la
interfaz de usuario).
14
ThreadStart job = new ThreadStart(HacerAlgo);
Thread thread = new Thread(job);
thread.Start();
3 - ¿Multithreading vs. Parallism?
15
Escenario nº1
Escenario nº2
3 - ¿Multithreading vs. Parallism?
Una aplicación puede incrementar el número de threads
para producir la sensación de que varios procesos se
llevan a cabo al mismo tiempo.
Pero sólo es paralelismo REAL si existen varios cores que
los ejecuten en paralelo.
16
3 1 1 1
varios cores
3 - ¿Multithreading vs. Parallism?
• Conclusión: Se parece pero no es lo mismo
• Podemos tener multithreading en una
estación con un solo core, pero sólo podemos
tener paralelismo real en una estación multi-
core.
• Error clásico: Como desarrolladores, utilizar
paralelismo en una máquina virtual (con un
solo core), y nos pensamos que estamos
haciendo paralelismo ->NOR!
17
3 - ¿Multithreading vs. Parallism?
• Esto SI es paralelismo 
18
3 - ¿Multithreading vs. Parallism?
• Y más vale que nos preparemos:
19
4 - Paralelismo en .NET 4.0
Microsoft Task Parallel Library (TPL)
20
4 - Paralelismo en .NET 4.0
LINQ - PLINQ
• Proporciona
extensiones
del lenguaje
para poder
utilizar
paralelismo en
nuestras
consultas
LINQ.
DATA - Parallel
• Situaciones en
las que se
realiza la
misma
operación al
mismo tiempo
sobre los
elementos de
un origen de
colección o
matriz.
TASKS - Task
• Una tarea
representa
una operación
asíncrona, se
asemeja a la
creación de un
Thread o un
ThreadPool,
pero a un nivel
más alto de
abstracción.
Concurrent
• Proporcionan
mecanismos
para
compartir
colecciones y
elementos
entre varios
hilos de
ejecución
(Thread-safe).
Más sencillo Más complejo
21
LINQ
4 - Paralelismo en .NET 4.0
PLINQ
22
Devuelve colecciones IEnumerable<T> / IQueryable<T>
Devuelve colecciones ParallelQuery<T>
PLINQ
4 - Paralelismo en .NET 4.0
AsParallel();
AsOrdered();
ForAll(action);
WithDegreeOfParallelism(ncores);
WithCancellation(CancellationToken);
WithMergeOptions(ParallelMergeOptions);
WithExecutionMode(ParallelExecutionMode);
ParallelQuery
23
Demo 1 {PLINQ}
• Partimos de una sencilla consulta LINQ, que
calcula los números primos hasta 10.000.000
• El objetivo es transformar esta consulta en
una consulta de ejecución paralela, mediante
el uso de PLINQ.
• Posteriormente veremos la diferencia de
tiempo de ejecución entre ambas.
24
Demo 1 {PLINQ}
public static bool IsPrime(int candidate)
{
if (candidate == 1) return true;
if ((candidate & 1) == 0)
{
if (candidate == 2) return true;
else return false;
}
for (int i = 3; (i * i) <= candidate; i += 2)
{
if ((candidate % i) == 0)
return false;
}
return candidate != 1;
}
25
private void getPrimesLINQ()
{
int[] array = Enumerable.Range(1, 10000000).ToArray();
clock.Restart();
int[] primesLINQ =
(from x in array
where IsPrime(x) select x).ToArray();
var list = primesLINQ.Take(100).ToList();
showValues(list);
clock.Stop();
elapsedTimeLabel.Text = clock.
ElapsedMilliseconds.ToString("n");
}
Demo 1 {PLINQ}
26
private void getPrimesPLINQ()
{
int[] array = Enumerable.Range(1, 10000000).ToArray();
clock.Restart();
int[] primesLINQ =
(from x in array.AsParallel()
where IsPrime(x) select x).ToArray();
var list = primesLINQ.Take(100).ToList();
showValues(list);
clock.Stop();
elapsedTimeLabel.Text = clock.
ElapsedMilliseconds.ToString("n");
}
Demo 1 {PLINQ}
27
private void getPrimesPLINQ()
{
int[] array = Enumerable.Range(1, 10000000).ToArray();
clock.Restart();
int[] primesLINQ =
(from x in array.AsParallel().AsOrdered()
where IsPrime(x) select x).ToArray();
var list = primesLINQ.Take(100).ToList();
showValues(list);
clock.Stop();
elapsedTimeLabel.Text = clock.
ElapsedMilliseconds.ToString("n");
}
Demo 1 {PLINQ}
28
private void getPrimesPLINQ()
{
int[] array = Enumerable.Range(1, 10000000).ToArray();
clock.Restart();
int[] primesLINQ =
(from x in array.AsParallel().AsOrdered()
.WithDegreeOfParallelism(numcores))
where IsPrime(x) select x).ToArray();
var list = primesLINQ.Take(100).ToList();
showValues(list);
clock.Stop();
elapsedTimeLabel.Text = clock.
ElapsedMilliseconds.ToString("n");
}
Demo 1 {PLINQ}
29
Demo 1 online
{PLINQ}
30
Demo 2 {PLINQ}
• Recorrer el árbol de directorios del sitio y
mostrar información de cada fichero.
• Uso de ForAll para aplicar una acción a todos
los elementos devueltos por un objeto de tipo
«ParallelQuery».
• Usado para sustituir a For / ForEach
ParallelQuery<T>.ForAll<T>(Action<T> action);
31
Demo 2 {PLINQ}
private void printInfo(string filename)
{
FileInfo f = new FileInfo(filename);
byte[] bytes = File.ReadAllBytes(f.FullName);
FileSecurity fs = f.GetAccessControl();
IdentityReference identity = fs.GetOwner(typeof(NTAccount));
IdentityReference group = fs.GetGroup(typeof(NTAccount));
string s = string.Format(
"file '{0}' ({1} kb), owner '{2}' ({3}), accesed at '{4}'",
f.Name, (f.Length / 1024).ToString("n2"),
identity.Value, group.Value, f.LastAccessTime);
filesinfoListBox.Items.Add(s);
}
32
Demo 2 {PLINQ}
private void getFilesForEach()
{
filesinfoListBox.Items.Clear();
clock.Restart();
var files = Directory.EnumerateFiles(
Server.MapPath(""), "*.*",
SearchOption.AllDirectories);
foreach (string s in files)
{
printInfo(s);
}
clock.Stop();
elapsedTimeLabel2.Text = clock.
ElapsedMilliseconds.ToString("n2");
}
33
Demo 2 {PLINQ}
private void getFilesParallelForAll()
{
filesinfoListBox.Items.Clear();
clock.Restart();
var files = Directory.EnumerateFiles(
Server.MapPath(""), "*.*",
SearchOption.AllDirectories).AsParallel();
files.ForAll<string>(p => printInfo(p));
clock.Stop();
elapsedTimeLabel2.Text = clock.
ElapsedMilliseconds.ToString("n2");
}
34
Demo 2 online
{PLINQ}
35
4 - Paralelismo en .NET 4.0
Parallel.For
Parallel.ForEach
Parallel.Invoke
Parallel
36
Ejemplo en
la demo nº5
Extensiones para el trabajo secuencial sobre datos.
Demo 3 {Parallel}
• Calcular los n primeros números de
la serie de Fibbonacci.
• Veremos como usar la versión paralela del
clásico bucle For (Parallel.For)
• Compararemos la diferencia de tiempo entre
ambas (For vs. Parallel.For).
37
Demo 3 {Parallel}
static int Fibonacci(int x)
{
if (x <= 1) return 1;
return
Fibonacci(x - 1) +
Fibonacci(x - 2);
}
38
Demo 3 {Parallel}
private void calculateFibonacciFor()
{
clock.Restart();
fibonacciListBox.Items.Clear();
for (int i = 1; i <= 40; i++)
{
fibonacciListBox.Items.Add(
Fibonacci(i).ToString());
}
clock.Stop();
elapsedTimeLabel.Text = clock.
ElapsedMilliseconds.ToString("n2");
}
39
Demo 3 {Parallel}
private void calculateFibonacciParallelFor()
{
clock.Restart();
fibonacciListBox.Items.Clear();
Parallel.For(1, 40, i =>
{
fibonacciListBox.Items.Add(
Fibonacci(i).ToString());
});
clock.Stop();
elapsedTimeLabel.Text = clock.
ElapsedMilliseconds.ToString("n2");
}
40
Demo 3 online
{Parallel}
41
Demo 4 {Parallel}
• Crear un pequeño cliente de RSS para obtener los
feeds de algunos blogs mediante LINQ2XML.
• Veremos como usar la versión paralela del clásico
bucle ForEach (Parallel.ForEach)
• Compararemos la diferencia de tiempo entre
ambas (ForEach vs. Parallel.ForEach ).
42
Demo 4 {Parallel}
public class FeedDefinition
{
public string Name { get; set; }
public string Url { get; set; }
public DateTime Date { get; set; }
public int NumComments { get; set; }
}
43
Clase para almacenar información de cada uno de los posts:
Demo 4 {Parallel}
List<string> urls = new List<string>();
private void addUrls()
{
urls.Clear();
urls.Add("http://weblogs.asp.net/scottgu/rss.aspx");
urls.Add("http://andorradotnet.com/blogs/MainFeed.aspx");
urls.Add("http://geeks.ms/blogs/MainFeed.aspx");
urls.Add("http://feeds2.feedburner.com/CienciaKanija");
}
44
Demo 4 {Parallel}
public List<FeedDefinition> loadFeeds(string path)
{
try
{
XDocument feedxml = XDocument.Load(path);
var feeds = from feed in feedxml.Descendants("item")
select new FeedDefinition
{
Name = feed.Element("title").Value,
Url = feed.Element("link").Value,
Date = DateTime.Parse(
feed.Element("pubDate").Value),
NumComments = int.Parse(
feed.Element(slashNamespace +
"comments").Value)
};
return feeds.ToList();
}
catch (Exception)
return null;
}
}
45
Demo 4 {Parallel}
private void getFeedsForEach()
{
clock.Restart();
addUrls();
List<FeedDefinition> allfeeds =
new List<FeedDefinition>();
foreach (var url in urls)
{
allfeeds.AddRange(loadFeeds(url));
}
showFeeds(allfeeds);
clock.Stop();
elapsedTimeLabel2.Text = clock.
ElapsedMilliseconds.ToString("n2");
}
46
Demo 4 {Parallel}
private void getFeedsParallelForEach()
{
clock.Restart();
addUrls();
List<FeedDefinition> allfeeds =
new List<FeedDefinition>();
Parallel.ForEach(urls, url =>
{
allfeeds.AddRange(loadFeeds(url));
});
showFeeds(allfeeds);
clock.Stop();
elapsedTimeLabel2.Text = clock.
ElapsedMilliseconds.ToString("n2");
}
47
Demo 4 online
{Parallel}
48
Demo 5 {TASK class}
• Ejecutar tareas implícitamente (Invoke):
public void InvokeSample()
{
Parallel.Invoke(() => {
Console.WriteLine("Begin first task...");
GetLongestWord(words);
}, // close first Action
() => {
Console.WriteLine("Begin second task...");
GetMostCommonWords(words);
}, //close second Action
() => {
Console.WriteLine("Begin third task...");
GetCountForWord(words, "species");
} //close third Action
); //close parallel.invoke
}
49
Demo 5 {TASK class}
• Ejecutar tareas explícitamente (Task class):
Task t1 = Task.Factory.StartNew(() => DoSomething());
50
Task t1 = new Task(() => DoSomething());
t1.Start();
var t1 = Task.Factory.StartNew<int>(() => DoSomething());
Task.WaitAny(t1);
int i = t1.Result;
Demo 5 {TASK class}
• Encadenar tareas (ContinueWith):
static void SimpleContinuation()
{
string path = @"C:userspublicTPLTestFolder";
try
{
var firstTask = new Task(() => CopyDataIntoTempFolder(path));
var secondTask = firstTask.ContinueWith((t) => CreateSummaryFile(path));
firstTask.Start();
}
catch (AggregateException e)
{
Console.WriteLine(e.Message);
}
}
51
Demo 5 {Task}
• Usar la clase Task para ejecutar varias tareas
en paralelo.
• Aplicar filtros a imágenes (1024x768 ~ 1Mb)
• El código de los filtros usa ‘unsafe’ para
ejecutar código con punteros
¿Alguien de VB en la sala ?
52
Demo 5 {TASK class}
private void ApplyFiltersSequentially()
{
clock.Restart();
ApplyFilterImage1();
ApplyFilterImage2();
ApplyFilterImage3();
ApplyFilterImage4();
ApplyFilterImage5();
ApplyFilterImage6();
clock.Stop();
elapsedTimeLabel.Text = clock.ElapsedMilliseconds.ToString("n");
}
53
private void ApplyFiltersParallel()
{
clock.Restart();
Task t1 = Task.Factory.StartNew(() => ApplyFilterImage1());
Task t2 = Task.Factory.StartNew(() => ApplyFilterImage2());
Task t3 = Task.Factory.StartNew(() => ApplyFilterImage3());
Task t4 = Task.Factory.StartNew(() => ApplyFilterImage4());
Task t5 = Task.Factory.StartNew(() => ApplyFilterImage5());
Task t6 = Task.Factory.StartNew(() => ApplyFilterImage6());
Task.WaitAll(t1, t2, t3, t4, t5, t6);
clock.Stop();
elapsedTimeLabel.Text = clock.ElapsedMilliseconds.ToString("n");
}
Demo 5 {TASK class}
54
Demo 5 {TASK class}
private void ApplyFilterImage1()
{
Bitmap b = (Bitmap)System.Drawing.Image.FromFile(
Server.MapPath("~/Images/Penguins.jpg"));
b.Invert().Save(Server.MapPath("~/Images/PenguinsInvert.jpg"));
img1.ImageUrl = "~/Images/PenguinsInvert.jpg";
}
private void ApplyFilterImage2()
{
Bitmap b = (Bitmap)System.Drawing.Image.FromFile(
Server.MapPath("~/Images/Desert.jpg"));
b.Grayscale().Save(Server.MapPath("~/Images/DesertGrayscale.jpg"));
img2.ImageUrl = "~/Images/DesertGrayscale.jpg";
}
55
Demo 5 online
{TASK class}
56
Demo 6 {Thread.Priority}
57
• Pregunta: ¿Es posible establecer la prioridad
de un thread en tiempo de ejecución?
• Respuesta: SI en función del entorno, pero en
un entorno multicore potente no tiene
demasiado sentido, ya que el S.O. siempre se
reserva la opción de modificarla.
• Aviso: Existen detractores de cambiar la
prioridad a nivel de thread:
stackoverflow.com , codinghorror.com
Demo 6 {Thread.Priority}
58
public long StartCount(ThreadPriority threadpriority)
{
Thread.CurrentThread.Priority = threadpriority;
long threadCount = 0;
while (LoopSwitch)
{
Thread.Sleep(1);
threadCount++;
}
return threadCount;
}
public enum ThreadPriority
{
Lowest = 0,
BelowNormal = 1,
Normal = 2,
AboveNormal = 3,
Highest = 4,
}
Demo 6 {Thread.Priority}
59
ThreadPriority rabbitPriority =
(ThreadPriority)DropDownList1.SelectedIndex;
ThreadPriority turtlePriority =
(ThreadPriority)DropDownList2.SelectedIndex;
Task<long> t1 = Task.Factory.StartNew<long>
(() => priorityTest.StartCount(rabbitPriority));
Task<long> t2 = Task.Factory.StartNew<long>
(() => priorityTest.StartCount(turtlePriority));
Demo 6 online
{Thread.Priority}
60
Demo 7 {Concurrence}
61
• En un entorno concurrente es bastante
probable encontrarse con situaciones de
bloqueos, o de elementos eliminados por
otros threads.
• NET 4.0 proviene de un conjunto de
colecciones specializadas thread-safe:
System.Collections.Concurrent
Demo 7 {Concurrence}
62
• Mostrar un ejemplo (exagerado!) de cómo en
un entorno multithread, los elementos de una
colección pueden ser modificados o eliminados
por otro thread y provocar un error en tiempo
de ejecución.
• Para prevenir estos errores veremos como usar
un ConcurrentDictionary y su método
TryUpdate.
Demo 7 {Concurrence}
63
Dictionary<int, Point> points1 = new Dictionary<int, Point>();
ConcurrentDictionary<int, Point> points2 =
new ConcurrentDictionary<int, Point>();
private void FillCollection()
{
points1.Clear();
points2.Clear();
Random r = new Random(DateTime.Today.Millisecond);
for (int i = 0; i < 100; i++)
{
int v = r.Next(1, 25);
points1.Add(i, new Point(v, v));
points2.TryAdd(i, new Point(v, v));
}
}
1 (20, 5)
2 (11,16)
3 (3,6)
4 (8,2)
5 (19,25)
Demo 7 {Concurrence}
64
Lanzamos dos tareas en paralelo, la primera intenta
modificar un elemento del diccionario (5), mientras que
la segunda borra todos los elementos del diccionario:
protected void Button1_Click(
object sender, EventArgs e)
{
FillCollection();
Task t1 = new Task(() => UpdateDictionary());
t1.Start();
Task t2 = new Task(() => ClearDictionary());
t2.Start();
Task.WaitAll(t1, t2);
}
Demo 7 {Concurrence}
65
private void UpdateDictionary()
{
if (points1.ContainsKey(5))
{
Thread.Sleep(2000);
try
{
Point p = points1[5]; //<- ERROR!!!
p.X = 666;
p.Y = 666;
messagesListBox.Items.Insert(0,
string.Format("Changed successfully: p.X = {0}", p.X));
}
catch (Exception ex)
{
messagesListBox.Items.Insert(0,
string.Format("Error, {0}", ex.Message));
}
}
}
Demo 7 {Concurrence}
66
private void UpdateConcurrentDictionary()
{
Point oldp = points2[5];
Point newp = new Point(666, 666);
if (points2.TryUpdate(5, newp, oldp))
{
messagesListBox.Items.Insert(0,
string.Format(
"Changed successfully: p.X = {0}", newp.X));
}
else
{
messagesListBox.Items.Insert(0,
string.Format("Error, key and value not found!"));
}
}
Demo 7 online
{Concurrence}
67
Demo 7 {Concurrence}
68
Thread-safe Collections in .NET Framework 4
and Their Performance Characteristics
That’s all folks!
Dubtes? Dudas? Doubts?
Lluís Franco
lfranco@ordeeno.com
69

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Multitarea e hilos en java con ejemplos
Multitarea e hilos en java con ejemplosMultitarea e hilos en java con ejemplos
Multitarea e hilos en java con ejemplos
 
Lab5 guia
Lab5 guiaLab5 guia
Lab5 guia
 
Docker y Kubernetes, en busca de la alta disponibilidad
Docker y Kubernetes, en busca de la alta disponibilidadDocker y Kubernetes, en busca de la alta disponibilidad
Docker y Kubernetes, en busca de la alta disponibilidad
 
Threads en Java
Threads en JavaThreads en Java
Threads en Java
 
GUIA 1 HILOS Y PROCESOS
GUIA 1 HILOS Y PROCESOSGUIA 1 HILOS Y PROCESOS
GUIA 1 HILOS Y PROCESOS
 
Intro to DTrace
Intro to DTraceIntro to DTrace
Intro to DTrace
 
Chap 15cpin
Chap 15cpinChap 15cpin
Chap 15cpin
 
Uso de hilos
Uso de hilosUso de hilos
Uso de hilos
 
Multitarea e hilos en java
Multitarea e hilos en javaMultitarea e hilos en java
Multitarea e hilos en java
 
Java Threads (Hilos en Java)
Java Threads (Hilos en Java)Java Threads (Hilos en Java)
Java Threads (Hilos en Java)
 
Apache Storm: Desarrollo
Apache Storm: DesarrolloApache Storm: Desarrollo
Apache Storm: Desarrollo
 
2o departamental Programacion 3
2o departamental Programacion 32o departamental Programacion 3
2o departamental Programacion 3
 
PCJ Sesión 9: Threads
PCJ Sesión 9: ThreadsPCJ Sesión 9: Threads
PCJ Sesión 9: Threads
 
Networking
NetworkingNetworking
Networking
 
Chap 15bpin
Chap 15bpinChap 15bpin
Chap 15bpin
 
Realidad Aumentada 01 documentacion tapir
Realidad Aumentada 01 documentacion tapirRealidad Aumentada 01 documentacion tapir
Realidad Aumentada 01 documentacion tapir
 
Update Big Data 2014
Update Big Data 2014Update Big Data 2014
Update Big Data 2014
 
PEP-3156: Async I/O en Python
PEP-3156: Async I/O en PythonPEP-3156: Async I/O en Python
PEP-3156: Async I/O en Python
 
Programación multihebra en java
Programación multihebra en javaProgramación multihebra en java
Programación multihebra en java
 
Manuel Blanco - GNU/Linux Binary Exploitation I&II [rooted2018]
Manuel Blanco - GNU/Linux Binary Exploitation I&II [rooted2018]Manuel Blanco - GNU/Linux Binary Exploitation I&II [rooted2018]
Manuel Blanco - GNU/Linux Binary Exploitation I&II [rooted2018]
 

Semelhante a News40 Parallel Computing

Task Parallel Library 2014
Task Parallel Library 2014Task Parallel Library 2014
Task Parallel Library 2014Lluis Franco
 
Sistemas operativos unidad 2
Sistemas operativos unidad 2Sistemas operativos unidad 2
Sistemas operativos unidad 2Luis Cigarroa
 
Arquitectura del computador trabajo finalizado
Arquitectura del computador trabajo finalizadoArquitectura del computador trabajo finalizado
Arquitectura del computador trabajo finalizadojose264806
 
DotNet 2019 | Pablo Santos Luaces - Como migrar un producto multiplataforma a...
DotNet 2019 | Pablo Santos Luaces - Como migrar un producto multiplataforma a...DotNet 2019 | Pablo Santos Luaces - Como migrar un producto multiplataforma a...
DotNet 2019 | Pablo Santos Luaces - Como migrar un producto multiplataforma a...Plain Concepts
 
Multithreading a la manera de Delphi
Multithreading a la manera de DelphiMultithreading a la manera de Delphi
Multithreading a la manera de DelphiMayra Mendieta
 
arquitectura del computador
arquitectura del computador arquitectura del computador
arquitectura del computador baryruiz
 
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAVíctor Bolinches
 
Como hacer que tus aplicaciones saquen mejor provecho a los procesadores disp...
Como hacer que tus aplicaciones saquen mejor provecho a los procesadores disp...Como hacer que tus aplicaciones saquen mejor provecho a los procesadores disp...
Como hacer que tus aplicaciones saquen mejor provecho a los procesadores disp...Andrés Iturralde
 
arquitectura del computador 1
arquitectura del computador 1arquitectura del computador 1
arquitectura del computador 1baryruiz
 
arquitectura del computador
arquitectura del computador arquitectura del computador
arquitectura del computador baryruiz
 
Nachos sistema operativo
Nachos sistema operativoNachos sistema operativo
Nachos sistema operativomahc83
 
Programacion en ambientes heterogeneos
Programacion en ambientes heterogeneosProgramacion en ambientes heterogeneos
Programacion en ambientes heterogeneositatitat
 
Estructura básica de un Sistema Operativo
Estructura básica de un Sistema Operativo Estructura básica de un Sistema Operativo
Estructura básica de un Sistema Operativo lizbethvazquezramirez
 
programacion concurrente java.pptx
programacion concurrente java.pptxprogramacion concurrente java.pptx
programacion concurrente java.pptxjuan gonzalez
 

Semelhante a News40 Parallel Computing (20)

Task Parallel Library 2014
Task Parallel Library 2014Task Parallel Library 2014
Task Parallel Library 2014
 
Sistemas operativos unidad 2
Sistemas operativos unidad 2Sistemas operativos unidad 2
Sistemas operativos unidad 2
 
Arquitectura del computador trabajo finalizado
Arquitectura del computador trabajo finalizadoArquitectura del computador trabajo finalizado
Arquitectura del computador trabajo finalizado
 
DotNet 2019 | Pablo Santos Luaces - Como migrar un producto multiplataforma a...
DotNet 2019 | Pablo Santos Luaces - Como migrar un producto multiplataforma a...DotNet 2019 | Pablo Santos Luaces - Como migrar un producto multiplataforma a...
DotNet 2019 | Pablo Santos Luaces - Como migrar un producto multiplataforma a...
 
Multithreading a la manera de Delphi
Multithreading a la manera de DelphiMultithreading a la manera de Delphi
Multithreading a la manera de Delphi
 
arquitectura del computador
arquitectura del computador arquitectura del computador
arquitectura del computador
 
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
 
Como hacer que tus aplicaciones saquen mejor provecho a los procesadores disp...
Como hacer que tus aplicaciones saquen mejor provecho a los procesadores disp...Como hacer que tus aplicaciones saquen mejor provecho a los procesadores disp...
Como hacer que tus aplicaciones saquen mejor provecho a los procesadores disp...
 
arquitectura del computador 1
arquitectura del computador 1arquitectura del computador 1
arquitectura del computador 1
 
arquitectura del computador
arquitectura del computador arquitectura del computador
arquitectura del computador
 
Lps 17 hilos
Lps 17 hilosLps 17 hilos
Lps 17 hilos
 
Nachos sistema operativo
Nachos sistema operativoNachos sistema operativo
Nachos sistema operativo
 
Programacion en ambientes heterogeneos
Programacion en ambientes heterogeneosProgramacion en ambientes heterogeneos
Programacion en ambientes heterogeneos
 
Estructura de un Sistema Operativo
Estructura de un Sistema Operativo Estructura de un Sistema Operativo
Estructura de un Sistema Operativo
 
Estructura básica de un Sistema Operativo
Estructura básica de un Sistema Operativo Estructura básica de un Sistema Operativo
Estructura básica de un Sistema Operativo
 
computación paralela
computación paralelacomputación paralela
computación paralela
 
Aso 3
Aso 3Aso 3
Aso 3
 
programacion concurrente java.pptx
programacion concurrente java.pptxprogramacion concurrente java.pptx
programacion concurrente java.pptx
 
intro.pptx
intro.pptxintro.pptx
intro.pptx
 
Paralelismo Concurrencia.ppt
Paralelismo Concurrencia.pptParalelismo Concurrencia.ppt
Paralelismo Concurrencia.ppt
 

Mais de Lluis Franco

Bienvenida al GAPAND 2016
Bienvenida al GAPAND 2016Bienvenida al GAPAND 2016
Bienvenida al GAPAND 2016Lluis Franco
 
Async best practices DotNet Conference 2016
Async best practices DotNet Conference 2016 Async best practices DotNet Conference 2016
Async best practices DotNet Conference 2016 Lluis Franco
 
Async Best Practices
Async Best PracticesAsync Best Practices
Async Best PracticesLluis Franco
 
Novetats Visual Studio 2010
Novetats Visual Studio 2010Novetats Visual Studio 2010
Novetats Visual Studio 2010Lluis Franco
 
Codecamp 2009 Qué Hay De Nuevo Viejo
Codecamp 2009   Qué Hay De Nuevo ViejoCodecamp 2009   Qué Hay De Nuevo Viejo
Codecamp 2009 Qué Hay De Nuevo ViejoLluis Franco
 
Andorra Dot Net Event4 Assentant Bases
Andorra Dot Net  Event4  Assentant BasesAndorra Dot Net  Event4  Assentant Bases
Andorra Dot Net Event4 Assentant BasesLluis Franco
 

Mais de Lluis Franco (7)

Bienvenida al GAPAND 2016
Bienvenida al GAPAND 2016Bienvenida al GAPAND 2016
Bienvenida al GAPAND 2016
 
Async best practices DotNet Conference 2016
Async best practices DotNet Conference 2016 Async best practices DotNet Conference 2016
Async best practices DotNet Conference 2016
 
Async Best Practices
Async Best PracticesAsync Best Practices
Async Best Practices
 
Infoxication
InfoxicationInfoxication
Infoxication
 
Novetats Visual Studio 2010
Novetats Visual Studio 2010Novetats Visual Studio 2010
Novetats Visual Studio 2010
 
Codecamp 2009 Qué Hay De Nuevo Viejo
Codecamp 2009   Qué Hay De Nuevo ViejoCodecamp 2009   Qué Hay De Nuevo Viejo
Codecamp 2009 Qué Hay De Nuevo Viejo
 
Andorra Dot Net Event4 Assentant Bases
Andorra Dot Net  Event4  Assentant BasesAndorra Dot Net  Event4  Assentant Bases
Andorra Dot Net Event4 Assentant Bases
 

News40 Parallel Computing

  • 1. Parallel Computing with .NET 4.0 Sacando partido al multi-core Lluís Franco - AndorraDotNet
  • 2. Agenda 1. Programación paralela ¿Queéloqueé? 2. Un poco de historia y algunos conceptos. 3. ¿Multithreading versus Parallel? 4. Paralelismo en .NET 4.0 (PLINQ, Parallel, Task) 5. Demos… 6. Demos…… 7. Y si… más demos  2
  • 4. 1 - ¿Y eso queéloqueé? ¿Esto? 4
  • 5. 1 - ¿Y eso queéloqueé? ¿Acaso esto? 5
  • 6. 1 - ¿Y eso queéloqueé? Wikipedia dixit: “La computación paralela es una técnica de programación en la que muchas instrucciones se ejecutan simultáneamente. Se basa en el principio de que los problemas grandes se pueden dividir en partes más pequeñas que pueden resolverse de forma concurrente”. “Existen varios tipos de computación paralela: paralelismo a nivel de bit, paralelismo a nivel de instrucción, paralelismo de datos y paralelismo de tareas”. “Durante muchos años, la computación paralela se ha aplicado en la computación de altas prestaciones, pero el interés en ella ha aumentado en los últimos años debido a las restricciones físicas que impiden el escalado en frecuencia”. 6
  • 7. 1 - ¿Y eso queéloqueé? La Ley de Moore expresa que aproximadamente cada 18 meses (*) se duplica el número de transistores en un circuito integrado. Se trata de una ley empírica, formulada por el co-fundador de Intel, Gordon E. Moore el 19 de abril de 1965, cuyo cumplimiento se ha podido constatar hasta hoy. Ley de Moore: (*) 2 años (1975). 7
  • 8. 1 - ¿Y eso queéloqueé? • La ley de Moore ha muerto: – Tecnología actual 32 nanómetros – Límite 18 nanómetros (cambios) – Se alcanzará aprox. en 2014 • Solución: – Más núcleos – Computación en paralelo – INTEL / AMD / NVIDIA (CUDA) «La materia presenta efectos cuánticos que harían necesaria una tecnología diferente para seguir realizando cálculos a ese nivel». Stephen Hawking 8
  • 9. 2 – Un poco de historia ¿Alguien recuerda los CRAY? 1976: Es uno de los supercomputadores más conocidos y exitosos de la historia, y de los más potentes en su época 9
  • 10. 2 – Un poco de historia ¿Y a Deep Blue? 1997: El primer ordenador en batir a un gran maestro (Garry Kasparov) 10
  • 11. 2 – Algunos conceptos Procesos & Threads en un sistema operativo 11 Un proceso proporciona los recursos necesarios para ejecutar un programa. Contiene un espacio de memoria virtual, código ejecutable, un contexto de seguridad, un identificador de proceso único, variables de entorno, y al menos un thread de ejecución. Cada proceso se inicia con un único thread, a menudo llamado thread principal, pero puede crear threads adicionales.
  • 12. 2 – Algunos conceptos Procesos & Threads en un sistema operativo 12 Un thread es la entidad dentro de un proceso que realmente ejecuta el código. Todos los threads de un proceso comparten los recursos y memoria virtual. Además, cada thread mantiene controladores de excepciones, una prioridad de programación, almacenamiento local, y un identificador de thread único. A más threads, más tiempo de CPU. Lógico, no?
  • 13. 3 - ¿Multithreading vs. Parallism? • Tipos de Multitarea: – Cooperativa o No Preemptiva (Windows anteriores a Win95/WinNT y MacOS): Cada proceso se ocupa de pasar el control al siguiente proceso. Un mal diseño de una aplicación y CATACRACK! – Preferente o Preemptiva (Windows Win95 y superiores, el resto de S.O. modernos): El sistema operativo es el encargado de ceder un tiempo a cada thread de cada proceso (time slice). Un mal diseño de una aplicación no implica el derrumbe del S.O. ya que se ejecutan en modo user. 13
  • 14. 3 - ¿Multithreading vs. Parallism? • Multithreading: – Técnica que consiste en manejar varios threads en una aplicación: – Permite realizar tareas asíncronas al ‘mismo tiempo’ (aunque realmente no es así). – No es trivial (más complejidad, depuración, acceso prohibido a la interfaz de usuario). 14 ThreadStart job = new ThreadStart(HacerAlgo); Thread thread = new Thread(job); thread.Start();
  • 15. 3 - ¿Multithreading vs. Parallism? 15 Escenario nº1 Escenario nº2
  • 16. 3 - ¿Multithreading vs. Parallism? Una aplicación puede incrementar el número de threads para producir la sensación de que varios procesos se llevan a cabo al mismo tiempo. Pero sólo es paralelismo REAL si existen varios cores que los ejecuten en paralelo. 16 3 1 1 1 varios cores
  • 17. 3 - ¿Multithreading vs. Parallism? • Conclusión: Se parece pero no es lo mismo • Podemos tener multithreading en una estación con un solo core, pero sólo podemos tener paralelismo real en una estación multi- core. • Error clásico: Como desarrolladores, utilizar paralelismo en una máquina virtual (con un solo core), y nos pensamos que estamos haciendo paralelismo ->NOR! 17
  • 18. 3 - ¿Multithreading vs. Parallism? • Esto SI es paralelismo  18
  • 19. 3 - ¿Multithreading vs. Parallism? • Y más vale que nos preparemos: 19
  • 20. 4 - Paralelismo en .NET 4.0 Microsoft Task Parallel Library (TPL) 20
  • 21. 4 - Paralelismo en .NET 4.0 LINQ - PLINQ • Proporciona extensiones del lenguaje para poder utilizar paralelismo en nuestras consultas LINQ. DATA - Parallel • Situaciones en las que se realiza la misma operación al mismo tiempo sobre los elementos de un origen de colección o matriz. TASKS - Task • Una tarea representa una operación asíncrona, se asemeja a la creación de un Thread o un ThreadPool, pero a un nivel más alto de abstracción. Concurrent • Proporcionan mecanismos para compartir colecciones y elementos entre varios hilos de ejecución (Thread-safe). Más sencillo Más complejo 21
  • 22. LINQ 4 - Paralelismo en .NET 4.0 PLINQ 22 Devuelve colecciones IEnumerable<T> / IQueryable<T> Devuelve colecciones ParallelQuery<T>
  • 23. PLINQ 4 - Paralelismo en .NET 4.0 AsParallel(); AsOrdered(); ForAll(action); WithDegreeOfParallelism(ncores); WithCancellation(CancellationToken); WithMergeOptions(ParallelMergeOptions); WithExecutionMode(ParallelExecutionMode); ParallelQuery 23
  • 24. Demo 1 {PLINQ} • Partimos de una sencilla consulta LINQ, que calcula los números primos hasta 10.000.000 • El objetivo es transformar esta consulta en una consulta de ejecución paralela, mediante el uso de PLINQ. • Posteriormente veremos la diferencia de tiempo de ejecución entre ambas. 24
  • 25. Demo 1 {PLINQ} public static bool IsPrime(int candidate) { if (candidate == 1) return true; if ((candidate & 1) == 0) { if (candidate == 2) return true; else return false; } for (int i = 3; (i * i) <= candidate; i += 2) { if ((candidate % i) == 0) return false; } return candidate != 1; } 25
  • 26. private void getPrimesLINQ() { int[] array = Enumerable.Range(1, 10000000).ToArray(); clock.Restart(); int[] primesLINQ = (from x in array where IsPrime(x) select x).ToArray(); var list = primesLINQ.Take(100).ToList(); showValues(list); clock.Stop(); elapsedTimeLabel.Text = clock. ElapsedMilliseconds.ToString("n"); } Demo 1 {PLINQ} 26
  • 27. private void getPrimesPLINQ() { int[] array = Enumerable.Range(1, 10000000).ToArray(); clock.Restart(); int[] primesLINQ = (from x in array.AsParallel() where IsPrime(x) select x).ToArray(); var list = primesLINQ.Take(100).ToList(); showValues(list); clock.Stop(); elapsedTimeLabel.Text = clock. ElapsedMilliseconds.ToString("n"); } Demo 1 {PLINQ} 27
  • 28. private void getPrimesPLINQ() { int[] array = Enumerable.Range(1, 10000000).ToArray(); clock.Restart(); int[] primesLINQ = (from x in array.AsParallel().AsOrdered() where IsPrime(x) select x).ToArray(); var list = primesLINQ.Take(100).ToList(); showValues(list); clock.Stop(); elapsedTimeLabel.Text = clock. ElapsedMilliseconds.ToString("n"); } Demo 1 {PLINQ} 28
  • 29. private void getPrimesPLINQ() { int[] array = Enumerable.Range(1, 10000000).ToArray(); clock.Restart(); int[] primesLINQ = (from x in array.AsParallel().AsOrdered() .WithDegreeOfParallelism(numcores)) where IsPrime(x) select x).ToArray(); var list = primesLINQ.Take(100).ToList(); showValues(list); clock.Stop(); elapsedTimeLabel.Text = clock. ElapsedMilliseconds.ToString("n"); } Demo 1 {PLINQ} 29
  • 31. Demo 2 {PLINQ} • Recorrer el árbol de directorios del sitio y mostrar información de cada fichero. • Uso de ForAll para aplicar una acción a todos los elementos devueltos por un objeto de tipo «ParallelQuery». • Usado para sustituir a For / ForEach ParallelQuery<T>.ForAll<T>(Action<T> action); 31
  • 32. Demo 2 {PLINQ} private void printInfo(string filename) { FileInfo f = new FileInfo(filename); byte[] bytes = File.ReadAllBytes(f.FullName); FileSecurity fs = f.GetAccessControl(); IdentityReference identity = fs.GetOwner(typeof(NTAccount)); IdentityReference group = fs.GetGroup(typeof(NTAccount)); string s = string.Format( "file '{0}' ({1} kb), owner '{2}' ({3}), accesed at '{4}'", f.Name, (f.Length / 1024).ToString("n2"), identity.Value, group.Value, f.LastAccessTime); filesinfoListBox.Items.Add(s); } 32
  • 33. Demo 2 {PLINQ} private void getFilesForEach() { filesinfoListBox.Items.Clear(); clock.Restart(); var files = Directory.EnumerateFiles( Server.MapPath(""), "*.*", SearchOption.AllDirectories); foreach (string s in files) { printInfo(s); } clock.Stop(); elapsedTimeLabel2.Text = clock. ElapsedMilliseconds.ToString("n2"); } 33
  • 34. Demo 2 {PLINQ} private void getFilesParallelForAll() { filesinfoListBox.Items.Clear(); clock.Restart(); var files = Directory.EnumerateFiles( Server.MapPath(""), "*.*", SearchOption.AllDirectories).AsParallel(); files.ForAll<string>(p => printInfo(p)); clock.Stop(); elapsedTimeLabel2.Text = clock. ElapsedMilliseconds.ToString("n2"); } 34
  • 36. 4 - Paralelismo en .NET 4.0 Parallel.For Parallel.ForEach Parallel.Invoke Parallel 36 Ejemplo en la demo nº5 Extensiones para el trabajo secuencial sobre datos.
  • 37. Demo 3 {Parallel} • Calcular los n primeros números de la serie de Fibbonacci. • Veremos como usar la versión paralela del clásico bucle For (Parallel.For) • Compararemos la diferencia de tiempo entre ambas (For vs. Parallel.For). 37
  • 38. Demo 3 {Parallel} static int Fibonacci(int x) { if (x <= 1) return 1; return Fibonacci(x - 1) + Fibonacci(x - 2); } 38
  • 39. Demo 3 {Parallel} private void calculateFibonacciFor() { clock.Restart(); fibonacciListBox.Items.Clear(); for (int i = 1; i <= 40; i++) { fibonacciListBox.Items.Add( Fibonacci(i).ToString()); } clock.Stop(); elapsedTimeLabel.Text = clock. ElapsedMilliseconds.ToString("n2"); } 39
  • 40. Demo 3 {Parallel} private void calculateFibonacciParallelFor() { clock.Restart(); fibonacciListBox.Items.Clear(); Parallel.For(1, 40, i => { fibonacciListBox.Items.Add( Fibonacci(i).ToString()); }); clock.Stop(); elapsedTimeLabel.Text = clock. ElapsedMilliseconds.ToString("n2"); } 40
  • 42. Demo 4 {Parallel} • Crear un pequeño cliente de RSS para obtener los feeds de algunos blogs mediante LINQ2XML. • Veremos como usar la versión paralela del clásico bucle ForEach (Parallel.ForEach) • Compararemos la diferencia de tiempo entre ambas (ForEach vs. Parallel.ForEach ). 42
  • 43. Demo 4 {Parallel} public class FeedDefinition { public string Name { get; set; } public string Url { get; set; } public DateTime Date { get; set; } public int NumComments { get; set; } } 43 Clase para almacenar información de cada uno de los posts:
  • 44. Demo 4 {Parallel} List<string> urls = new List<string>(); private void addUrls() { urls.Clear(); urls.Add("http://weblogs.asp.net/scottgu/rss.aspx"); urls.Add("http://andorradotnet.com/blogs/MainFeed.aspx"); urls.Add("http://geeks.ms/blogs/MainFeed.aspx"); urls.Add("http://feeds2.feedburner.com/CienciaKanija"); } 44
  • 45. Demo 4 {Parallel} public List<FeedDefinition> loadFeeds(string path) { try { XDocument feedxml = XDocument.Load(path); var feeds = from feed in feedxml.Descendants("item") select new FeedDefinition { Name = feed.Element("title").Value, Url = feed.Element("link").Value, Date = DateTime.Parse( feed.Element("pubDate").Value), NumComments = int.Parse( feed.Element(slashNamespace + "comments").Value) }; return feeds.ToList(); } catch (Exception) return null; } } 45
  • 46. Demo 4 {Parallel} private void getFeedsForEach() { clock.Restart(); addUrls(); List<FeedDefinition> allfeeds = new List<FeedDefinition>(); foreach (var url in urls) { allfeeds.AddRange(loadFeeds(url)); } showFeeds(allfeeds); clock.Stop(); elapsedTimeLabel2.Text = clock. ElapsedMilliseconds.ToString("n2"); } 46
  • 47. Demo 4 {Parallel} private void getFeedsParallelForEach() { clock.Restart(); addUrls(); List<FeedDefinition> allfeeds = new List<FeedDefinition>(); Parallel.ForEach(urls, url => { allfeeds.AddRange(loadFeeds(url)); }); showFeeds(allfeeds); clock.Stop(); elapsedTimeLabel2.Text = clock. ElapsedMilliseconds.ToString("n2"); } 47
  • 49. Demo 5 {TASK class} • Ejecutar tareas implícitamente (Invoke): public void InvokeSample() { Parallel.Invoke(() => { Console.WriteLine("Begin first task..."); GetLongestWord(words); }, // close first Action () => { Console.WriteLine("Begin second task..."); GetMostCommonWords(words); }, //close second Action () => { Console.WriteLine("Begin third task..."); GetCountForWord(words, "species"); } //close third Action ); //close parallel.invoke } 49
  • 50. Demo 5 {TASK class} • Ejecutar tareas explícitamente (Task class): Task t1 = Task.Factory.StartNew(() => DoSomething()); 50 Task t1 = new Task(() => DoSomething()); t1.Start(); var t1 = Task.Factory.StartNew<int>(() => DoSomething()); Task.WaitAny(t1); int i = t1.Result;
  • 51. Demo 5 {TASK class} • Encadenar tareas (ContinueWith): static void SimpleContinuation() { string path = @"C:userspublicTPLTestFolder"; try { var firstTask = new Task(() => CopyDataIntoTempFolder(path)); var secondTask = firstTask.ContinueWith((t) => CreateSummaryFile(path)); firstTask.Start(); } catch (AggregateException e) { Console.WriteLine(e.Message); } } 51
  • 52. Demo 5 {Task} • Usar la clase Task para ejecutar varias tareas en paralelo. • Aplicar filtros a imágenes (1024x768 ~ 1Mb) • El código de los filtros usa ‘unsafe’ para ejecutar código con punteros ¿Alguien de VB en la sala ? 52
  • 53. Demo 5 {TASK class} private void ApplyFiltersSequentially() { clock.Restart(); ApplyFilterImage1(); ApplyFilterImage2(); ApplyFilterImage3(); ApplyFilterImage4(); ApplyFilterImage5(); ApplyFilterImage6(); clock.Stop(); elapsedTimeLabel.Text = clock.ElapsedMilliseconds.ToString("n"); } 53
  • 54. private void ApplyFiltersParallel() { clock.Restart(); Task t1 = Task.Factory.StartNew(() => ApplyFilterImage1()); Task t2 = Task.Factory.StartNew(() => ApplyFilterImage2()); Task t3 = Task.Factory.StartNew(() => ApplyFilterImage3()); Task t4 = Task.Factory.StartNew(() => ApplyFilterImage4()); Task t5 = Task.Factory.StartNew(() => ApplyFilterImage5()); Task t6 = Task.Factory.StartNew(() => ApplyFilterImage6()); Task.WaitAll(t1, t2, t3, t4, t5, t6); clock.Stop(); elapsedTimeLabel.Text = clock.ElapsedMilliseconds.ToString("n"); } Demo 5 {TASK class} 54
  • 55. Demo 5 {TASK class} private void ApplyFilterImage1() { Bitmap b = (Bitmap)System.Drawing.Image.FromFile( Server.MapPath("~/Images/Penguins.jpg")); b.Invert().Save(Server.MapPath("~/Images/PenguinsInvert.jpg")); img1.ImageUrl = "~/Images/PenguinsInvert.jpg"; } private void ApplyFilterImage2() { Bitmap b = (Bitmap)System.Drawing.Image.FromFile( Server.MapPath("~/Images/Desert.jpg")); b.Grayscale().Save(Server.MapPath("~/Images/DesertGrayscale.jpg")); img2.ImageUrl = "~/Images/DesertGrayscale.jpg"; } 55
  • 56. Demo 5 online {TASK class} 56
  • 57. Demo 6 {Thread.Priority} 57 • Pregunta: ¿Es posible establecer la prioridad de un thread en tiempo de ejecución? • Respuesta: SI en función del entorno, pero en un entorno multicore potente no tiene demasiado sentido, ya que el S.O. siempre se reserva la opción de modificarla. • Aviso: Existen detractores de cambiar la prioridad a nivel de thread: stackoverflow.com , codinghorror.com
  • 58. Demo 6 {Thread.Priority} 58 public long StartCount(ThreadPriority threadpriority) { Thread.CurrentThread.Priority = threadpriority; long threadCount = 0; while (LoopSwitch) { Thread.Sleep(1); threadCount++; } return threadCount; } public enum ThreadPriority { Lowest = 0, BelowNormal = 1, Normal = 2, AboveNormal = 3, Highest = 4, }
  • 59. Demo 6 {Thread.Priority} 59 ThreadPriority rabbitPriority = (ThreadPriority)DropDownList1.SelectedIndex; ThreadPriority turtlePriority = (ThreadPriority)DropDownList2.SelectedIndex; Task<long> t1 = Task.Factory.StartNew<long> (() => priorityTest.StartCount(rabbitPriority)); Task<long> t2 = Task.Factory.StartNew<long> (() => priorityTest.StartCount(turtlePriority));
  • 61. Demo 7 {Concurrence} 61 • En un entorno concurrente es bastante probable encontrarse con situaciones de bloqueos, o de elementos eliminados por otros threads. • NET 4.0 proviene de un conjunto de colecciones specializadas thread-safe: System.Collections.Concurrent
  • 62. Demo 7 {Concurrence} 62 • Mostrar un ejemplo (exagerado!) de cómo en un entorno multithread, los elementos de una colección pueden ser modificados o eliminados por otro thread y provocar un error en tiempo de ejecución. • Para prevenir estos errores veremos como usar un ConcurrentDictionary y su método TryUpdate.
  • 63. Demo 7 {Concurrence} 63 Dictionary<int, Point> points1 = new Dictionary<int, Point>(); ConcurrentDictionary<int, Point> points2 = new ConcurrentDictionary<int, Point>(); private void FillCollection() { points1.Clear(); points2.Clear(); Random r = new Random(DateTime.Today.Millisecond); for (int i = 0; i < 100; i++) { int v = r.Next(1, 25); points1.Add(i, new Point(v, v)); points2.TryAdd(i, new Point(v, v)); } } 1 (20, 5) 2 (11,16) 3 (3,6) 4 (8,2) 5 (19,25)
  • 64. Demo 7 {Concurrence} 64 Lanzamos dos tareas en paralelo, la primera intenta modificar un elemento del diccionario (5), mientras que la segunda borra todos los elementos del diccionario: protected void Button1_Click( object sender, EventArgs e) { FillCollection(); Task t1 = new Task(() => UpdateDictionary()); t1.Start(); Task t2 = new Task(() => ClearDictionary()); t2.Start(); Task.WaitAll(t1, t2); }
  • 65. Demo 7 {Concurrence} 65 private void UpdateDictionary() { if (points1.ContainsKey(5)) { Thread.Sleep(2000); try { Point p = points1[5]; //<- ERROR!!! p.X = 666; p.Y = 666; messagesListBox.Items.Insert(0, string.Format("Changed successfully: p.X = {0}", p.X)); } catch (Exception ex) { messagesListBox.Items.Insert(0, string.Format("Error, {0}", ex.Message)); } } }
  • 66. Demo 7 {Concurrence} 66 private void UpdateConcurrentDictionary() { Point oldp = points2[5]; Point newp = new Point(666, 666); if (points2.TryUpdate(5, newp, oldp)) { messagesListBox.Items.Insert(0, string.Format( "Changed successfully: p.X = {0}", newp.X)); } else { messagesListBox.Items.Insert(0, string.Format("Error, key and value not found!")); } }
  • 68. Demo 7 {Concurrence} 68 Thread-safe Collections in .NET Framework 4 and Their Performance Characteristics
  • 69. That’s all folks! Dubtes? Dudas? Doubts? Lluís Franco lfranco@ordeeno.com 69