miércoles, 19 de septiembre de 2012

EL SDK Visualizador de Concurrencia: Técnicas Avanzadas de Visualización.

 

En el post anterior , pudimos verificar en diferentes escenarios el uso del visualizador de concurrencia, el dia de hoy quiero mostrarles unas técnicas mejoradas con el fin de obtener un mayo control sobre la dorma de visualizar los eventos mas significativos dentro de una aplicación.

Con el fin de ilustrar bien los comportamientos de la aplicación, voy a utilizar a manera de simulación aplicación simula el proceso que lleva a una persona del común ir al trabajo, Se simularan cambios de 4 procesos usando múltiples iteraciones (Cada Iteracion representa una hora en tiempo de simulación).

Para cada iteración la aplicación realiza los siguientes cuatro cálculos:

1. Levantarse.

2. Bañarse.

3. Desayunarse.

4. Salir.

En esta simulación se puede realizar en paralelo y usare C# y el Thread Poll para simular la carga de trabajo de paralelismo.

Sin explicar mucho el código a continuación presento el código con el cual trabajaremos:

static void Main(string[] args)

{

MarkerWriter miwriter =

new MarkerWriter(new Guid("9f34bddd-eae4-40c9-b668-91d78fc0b326"));

MarkerSeries series = miwriter.CreateMarkerSeries("");

GradoParalelismo = 2;

numIterations = 24;

DateTime simTime = new DateTime(2012, 09, 18, 0, 0, 0);

eventoManuales = new ManualResetEvent[GradoParalelismo];

for (int i = 0; i < eventoManuales.Length; i++)

{

eventoManuales[i] = new ManualResetEvent(false);

}

//Cada Iteracion representa una hora de las actividades del dia

for (int n = 0; n < numIterations; n++)

{

series.WriteFlag("Iteration " + n + ": time = " + simTime.TimeOfDay);

//Etapa 1 - Levantarse

for (int i = 0; i < GradoParalelismo; i++)

{

eventoManuales[i].Reset();

var span = series.EnterSpan("Levantadose");

TaskInfo ti = new TaskInfo("Levantadose", i);

ThreadPool.QueueUserWorkItem(Levantarse, ti);

Thread.Sleep(100);

span.Leave();

}

WaitHandle.WaitAll(eventoManuales);

//Etapa 2 -Bañarse

for (int i = 0; i < GradoParalelismo; i++)

{

eventoManuales[i].Reset();

var span = series.EnterSpan("bañandose");

TaskInfo ti = new TaskInfo("bañandose", i);

ThreadPool.QueueUserWorkItem(Banarse, ti);

Thread.Sleep(100);

span.Leave();

}

WaitHandle.WaitAll(eventoManuales);

//Etapa 3 - Desayunar

for (int i = 0; i < GradoParalelismo; i++)

{

eventoManuales[i].Reset();

var span = series.EnterSpan("Desayunandose");

TaskInfo ti = new TaskInfo("Desayunandose", i);

ThreadPool.QueueUserWorkItem(Desayunar, ti);

Thread.Sleep(100);

span.Leave();

}

WaitHandle.WaitAll(eventoManuales);

//Etapa 4 - Salir

for (int i = 0; i < GradoParalelismo; i++)

{

eventoManuales[i].Reset();

var span = series.EnterSpan("Saliendo a trabajar");

TaskInfo ti = new TaskInfo("Saliendo a trabajar", i);

ThreadPool.QueueUserWorkItem(Salir, ti);

Thread.Sleep(100);

span.Leave();

}

WaitHandle.WaitAll(eventoManuales);

simTime = simTime.AddHours(1);

}

Console.ReadKey();

}

Como podemos ver tenemos una variable estática llamada GradoParalelismo, el cual define la cantidad de hilos que van a participar de manera simultanea en la simulación.

Dado que los resultados de cada fase dependen de la fase anterior, usaremos una variable llamada (eventoManuales) con el fin de tener un punto de reset , de tal forma que los hilos no continuaran la siguiente fase hasta que todos hayan finalizado la fase actual.

En este ejemplo , Se ejecutara en una maquina con un Core i7 Processor. Con la variable GradoParalelismo = 2 y ejecuto el código en dos iteraciónes.

Con el fin de tener un idea generalizada de cómo se comporta la aplicación correremos el visualizador de concurrencia, para saber cuál de la etapas se encuentra más equilibrada y desde luego la duración de cada una de ellas.

La imagen que se presenta a continuación muestra el comportamiento de la aplicación sobre el visualizador de concurrencia.

Según la grafica anterior, lo que podemos visualizar, es que el hilo anterior encola los elementos de trabajo y los bloquea mientras avanza el programa. Como se puede visualizar existen varios hilos ejecutando el trabajo (Color Verde). Los hilos no están 100% ocupados, sin embargo , a partir de esta imagen es difícil saber a que horas se lleva cada fase.

En el post anterior , realizamos una introducción de como se usa un SPAN para demarcar la ejecución de una fase. Pero a diferencia del ejemplo anterior lo que desea realizar es tener un Marcador ( Marker) personalizado, en lugar de utilizar el predeterminado.

No hay comentarios:

Publicar un comentario