PiensoPienso: Respuesta de Paralelizando programas.

WolframEsto es una respuesta al post Paralelizando programas.

Viendo las respuestas que brindaron los lectores (gracias!), vemos 2 tipos de soluciones:

  • hacer submit
  • hacer shell con la opción que no espere a que termine.

de forma de hacer una llamada asincrónica (que no esperar_a que termine).

El problema mayor esta en limitar la cantidad de instancias que pueden correr en forma simultanea. Según el problema había que limitar a 8 la cantidad de procesos/thread simultáneos.

No estaba dicho el el problema, pero si se genera el programa en java/web, se puede utilizar el SUBMIT, con la propiedad SUBMIT_POOL_SIZE=8 en el client.cfg.

SUBMIT_POOL_SIZE es una propiedad implementada solo en java/web en el 2003, que esta buena y me entere hace muy poco de su existencia. Creo que puede ser interesante implementarla para el resto de las plataformas (.NET y Ruby), pues el tema de paralelismo va a ser cada vez mas necesario.

Si el programa es .NET, puede utilizarse el shell no modal, con un programa command line, y controlando que no existan mas de 8 procesos en la lista de procesos de Windows.

Con el código del Procedure CuentoProcesosEjecutando :

csharp         System.Diagnostics.Process[/* */] processes = System.Diagnostics.Process.GetProcessesByName([!&NombreProceso!]);  
csharp         [!&CantProcesos!] = processes.Length;


y el código que del proceso principal quedaria



for each where Procesado='N'
   &CantProcesos= Udp(PCuentoProcesosEjecutando,'aProceso_y_Marco')
   do while &CantProcesos >= &CantProcesosSimultaneos
      &err=sleep(&CantSegundosEspera)
       &CantProcesos= Udp(PCuentoProcesosEjecutando,'aProceso_y_Marco')
   enddo
   &Comando=format('aProceso_y_Marco.exe %1',&Clave)
   &Err=shell(&Comando,0)    //CON 0 No espera a que termine. 
endfor

El procedimiento Proceso_y_Marco deberia ser main y command line.

Conclusión



Creo que vamos a necesitar cada vez mas darle mas importancia a la ejecución en paralelo de varios tareas. Hay que buscar la forma de poder aprovechar mejor la cantidad de nucleos que tenemos en los procesadores actuales, por lo que nos vendría bien empezar a encontrar lugares donde la ejecucion paralelizada tenga sentido.



Por ejemplo, podria ser util, tener un pfor each, que ejecute en paralelo las sentencias que estan dentro del for each



for each (paralell=3)
//Codigo


endfor

Comentarios

  1. Lo del pool de submit en java es algo interesante, no lo conocía :)
    Yo no soy de recomendar el uso de submit, ya que existen algunos temitas con la implementación que no permiten un correcto monitoreo (jmx/wmi).

    Lo de controlarlo por cantidad de procesos con el mismo nombre no funcionaría si tienes N sistemas en el mismo servidor corriendo en paralelo (en mis servidores se da mucho eso de tener N ambientes de testing, o tener varias instancias producción cada una para clientes diferentes).

    Por eso recomendé tener un orquestador implementado en full GX que se encargue de ir procesando, implementando algo así como un buffer, de la forma que está implementando inclusive puede correr en ambiente Legacy como en Cobol o en RPG manejando Submit.
    Pero todo Win, no Web, el sistema Web "agenda" a procesar y el orquestador Win, procesa e instancia (no por Submit) cada ejecucción (si es Shell, cada corrida si es Java tiene su instancia de la JVM, en Win con .NET es un proceso separado).

    Irse por parámetros en CFG o implementaciones "nativas" es todo un tema, yo me voy más a implementaciones que puedan "portarse" de forma multiplataforma.

    Lo de paralelizar sentencias SQL es algo interesante, pero en realidad pienso que es un tema que debe de resolver la base de datos. Lo que le falta a genexus es el poder de encapsular más lógica procedural hacia +sentencias SQL, y dejar al DBMS que se encargue de la paralelización de todo el conjunto.

    El paralelizar la lógica procedural generada ( .NEt o Java, Ruby en Genexus) va a traer problemas con las transaccionabilidad, si tiro 3 lógicas procedurales en paralelo ¿cual es la que gana la carrera? el commit a quien afecta? si una cancela o hace rollback o pone un Exit? las otras cómo se deben de comportar?
    Hoy GeneXus la forma en que puede hacer es recorrer registros resultantes de una sentencia en SQL y por cada uno de ellos ejecutar código en diferentes hilos, esto daría todos los problemas que mencioné anteriormente y posiblemente algunos más.

    sin embargo en ejecuciones atómicas en donde alguien pone cabeza a la partición de datos a procesar y ejecuta N procesos a tomar cada "rango de datos" en paralelo tendiendo en cuenta en lo posible que no existan bloqueos cruzados entre cada vía de ejecución (que modifiquen mismo registros), lograrán mejoras importantes (inclusive con mensajería podrían implementarse procesamiento distribuido), esto claro, no corriendo en el hilo web, sino en un proceso separado.

    La implementación común de ráfagas de sentencias SQL permite una buena escalabilidad horizontal a nivel de appserver, desaprovechando generalmente la base de datos, tirando sentencias SQL más complejas con lógica procedural permitiría una escalabilidad menor, ya que la mayoría de los DBMS escalabilidad verticalmente, todo depende del tipo de aplicación que uno tenga la solución que necesitará implementar (procesamiento distribuido, paralelización y lógica procedural en la base de datos).

    La implementación de "Cola de Submit", procesamiento distribuido también puede implementarse con GeneXus si se implementa un orquestador + submit/shell y se usa el tipo de datos Queue o una tabla que lo simule (ojo con los bloqueos) para ir procesando cada mensaje emitido a la cola (lo que hoy todos manejan como Submit de la aplicación)

    ResponderBorrar
  2. Yo estuve usando el SUBMIT en varias instalaciones en la X al poco tiempo me sobrecargaba la memoria, viendo el JMX me di cuenta que dejaba instancias de memoria levantadas.

    ResponderBorrar
  3. Estimados.. gracias por estas ideas, y comentarios.
    Pude implementar un manejo de notificaciones Generico, donde paralelizo los envios mediante varios Thread.

    En particular la "accion" de notificar ( pueden ser webnotification, post a un WS, envio de email, etc) son tareas "atomicas" que el mensaje que se pasa tiene autocontenido todo para esa accion, entonces ejecuto y aviso que termino y puedo largar el siguiente, creo que eso simplifico esta solucion.
    Luego con un sistema de semaforos simples, coordino dichas acciones.

    Mucha gracias

    ResponderBorrar

Publicar un comentario

1) Lee el post
2) Poné tu opinión sobre el mismo.
Todos los comentarios serán leidos y la mayoría son publicados.

Entradas más populares de este blog

Aplicación monolítica o distribuida?

La nefasta influencia del golero de Cacho Bochinche en el fútbol uruguayo

Funcionalidades de GeneXus que vale la pena conocer: DATE Constants.