Concurrencia
y
Paralelismo
Evolución del Software.
Lo bueno, lo malo, lo necesario e incomodo.
Agenda
- Características
- Evolución y Revolución
- Moore - Amdahl y Page
- Concurrencia
- Paralelismo
- Scala
- Clojure
90's
Caracteristicas
- Mayor Complejidad
- Nuevas Estructuras
- Modelar el Dominio
- Reutilización
- Objetos
Lenguajes
Simula
Smalltalk
C++
Objective-C
Java
C#
Ruby
... y una bolsa interminable de ellos ...
Thinking in...
OOA & OOD & OOP
UML
Patterns
XP
Agile
DDD
TDD
BDD
Evolucion
Modelado Conceptual
Aumento de la Complejidad
Infraestructura
Diseño Participativo
Reutilizacion
revolucion
Big Data
Cloud
Integración - Coordinación - Disponibilidad
Tolerancia a fallos
Calidad
Multi-core
GPU
Ley de moore
Tendencia de crecimiento
Velocidad de procesamiento
Capacidad de almacenamiento
Aumentos exponenciales

Ley de Amdhal
Mejora en la ejecución al aumentar el número de procesadores
Es un modelo matemático que describe la relación entre la aceleración esperada de la implementación paralela de un algoritmo y la implementación serial del mismo algoritmo.
Tendencia
EL MUNDO DEL SOFTWARE ESTA CAMBIANDO INFLUIDO POR LA TENDENCIA EVOLUTIVA DEL HARDWARE

ley de Larry page
"Page's Law is sort of the opposite of Moore's Law," "Page's Law says that every 18 months software becomes twice as slow."
demanda
Productos o Servicios
Usuarios y Usabilidad
Funcionalidad
Confiable, Portable y Eficiente
Mantenimiento
Escalabilidad
En cuanto a las aplicaciones modernas...
escalabilidad
- Vertical (scaling up) - Concurrencia
- Horizontal (scaling out) - Distribucion
- Size - Recursos, Usuarios, Computo
- Localización
- Administración
- Disponibilidad - Fault Tolerance
- Performance
En lineas generales
Se busca desarrollar programas cada vez mas complejos con el uso de múltiples CPUs multicore y hasta incluir GPUs en la computación de procesos con la posibilidad de reducir el tiempo de ejecución de un programa.
ventajas
Tiempo de computo
Recursos
Acceso simultáneo
Mayor cohesión y menor acoplamiento entre tareas
Ahorro e inversión
desventajas
Programas mas complejos
Ejecuciones no determinísticas
Requiere un mayor grado de especialidad
Código difícil de depurar
determinismo
Algoritmo completamente predictivo si se conocen sus entradas, si estas son iguales producen siempre la misma salida.
Por ejemplo Tuning es una máquina de estado abstracta determinística.
concurrencia
Ejecución de programas de forma no determinística
Necesaria para implementar Paralelismo
Se pueden estar realizando dos o mas operaciones en el mismo tiempo o no. Depende del Paralelismo
Sincronización y Comunicación de ejecución en una o mas CPUs.
Paralelismo
Implica una ejecución simultánea de dos o mas operaciones en el mismo número de CPUs.
Necesita mecanismos de concurrencia para juntar las partes de los cálculos realizados.
Concurrencia y paralelismo
Programacion paralela
Ejecutar programas más rápidos en hardware paralelo
Programacion Concurrente
Manejar y administrar los Threads de ejecución concurrentes de manera explícita
Ambos son demasiados complicados y difíciles de editar, ejecutar y mejorar (bugs too hard)
PPP Grand Challenge
La necesidad de la computación paralela y concurrente llevada a cabo de manera fácil y segura es llamada PPP (Popular Parallel Programming). Este es el nuevo desafío.
Estamos frente a un nuevo paradigma en el desarrollo del Software?
Pero, por qué es tan importante?
Permite simular una ejecución en un entorno monocore.
Gestionar el acceso seguro a elementos compartidos y secciones críticas.
Garantizar que las operaciones siempre brindan los mismo resultados.
Reducir el tiempo de cómputo en programas de cualquier escala.
Mejora en la administración de los recursos.
El problema principal
non-determinism = parallel processing + mutable state
Non-determinism caused by concurrent threads accessing shared mutable state.
Soluciones
Threads. Locks. States
Sinchronization Blocks
Agents
Actors (base on Erlang)
Shared Memory
STM (Software Transactional Memory)
Futures
Soluciones
Collections:
- Parallel Collections
- Distributed Collections
Parallels DSL
Threads

Single Block

En el bloque el Thread se suspende
Threads (add concurrency)

Tiempos de Procesos y latencia
Thread por tarea (dividido en capas). Resultado sincrónico.

Tiempos de procesos y latencia
Paralelismo por capa de procesamiento - Asynchronous and Partial Results From Request/Response to Request Stream/Response Stream

El desafio
Parallel
Async
Distributed
Cómo hacer uso de la manera más eficiente los recursos multicore, GPUs, Clusters? Cómo manejar eventos asincronicos? Cómo responder frente a los delays y errores?
orientacion a objetos
Objects are characterized by state, identity and behavior
(Booch)
Abandonar la OO? Mantener la descomposición en el Análisis y Diseño
- Eliminar o reducir el uso de estado mutable
- Concentrarse en la funcionalidad (behavior)
- Apoyarse en la estructuras en lugar de las referencias
Programacion Funcional
- Funciones de primer nivel
- Closures
- Asignación simple
- Evaluación tardía
- Inferencia de tipos
- Optimización del tail call
- Efectos monadic
Programacion funcional
El computo se basa en la evaluación de funciones matemáticas, evitando los programas con estado y datos que pueden ser modificados.
Adoptar una visión más matemática del mundo en el que los programas
están compuestos por numerosas funciones que esperan una determinada
entrada y producen una determinada salida y en ocasiones otras
funciones.
JVM
Lo más relevante de Java es su máquina virtual (JVM)
Carga y almacenamiento
Aritmética
Conversión de tipos
Creación y manipulación de objetos
Gestión de pilas (push y pop)
Transferencias de control
Invocación y retorno a métodos
Excepciones
Java
public class DummyThread extends Thread implements
AccessPoint {
public void startListening(Properties props,
String interpreterName) {
this.setDaemon(false);
this.setName("GarbageCollectorInvoker");
this.start();
}
public void stopListening() {
stop=true;
synchronized (this){
notifyAll();
}
}
public boolean isListening() {
return !stop;
}
}
Java
public void run() {
int interval = 0;
try{
while(!stop){
try{
synchronized (this){
wait(interval);
System.gc();
}
}catch(Exception e){
log.error(e.getMessage());
}
}
}
Java
public class SocketEventHandler extends Handler {
public SocketEventHandler(SocketEventHandlersManager mgr){
super(mgr);
}
public void run(){
try {
Object message = null;
EventHandlersManager manager = (EventHandlersManager) getManager();
while (!stopProcessing){
changeState(Handler.States.WAITING);
message = manager.getNextMessageToSend();
if (message!=null){
this.sendMessageToClient(message);
changeState(Handler.States.WORKING);
}
}
}catch (InterruptedException e) {
}catch (Exception e) {
}finally{
changeState(Handler.States.DEAD);
}
}
}
Scala
Lenguaje de Programación de propósito general
JVM
Orientado a Objetos + Funcional
Sintácticamente mas liviano
Safe and Performant
Java vs Scala
public class Person {
public final String name;
public final int age;
Person(String name, int age){
this.name = name;
this.age = age;
}
}
class Person(val name: String, val age: int)
Java vs Scala
import java.util.ArrayList;
Person[] people;
Person[] minors;
Person[] adults;
{
ArrayList minorsList = new ArrayList();
ArrayList adultsList = new ArrayList();
for (int i = 0; i < people.length; i++)
(people[i].age < 18 ? minorsList : adultsList).add(people[i]);
minors = minorsList.toArray(people);
adults = adultsList.toArray(people);
}
Java vs Scala
Pattern matching
Infix method call
Function value
val people: Array[Person]
val (minors, adults) = people partition (_.age < 18)
Scala Parallel
Collections .par
parallel version of collection
val people: Array[Person]
val (minors, adults) = people.par partition (_.age < 18)
Sequences .seq
secuencial version of collection
Scala
class Rational(n: Int, d: Int) extends Ordered[Rational] {
def compare(that: Rational) =
(this.numer * that.denom) - (that.numer * this.denom)
require(d != 0)
private val g = gcd(n.abs, d.abs)
val numer = n / g
val denom = d / g
def this(n: Int) = this(n, 1)
def + (that: Rational): Rational =
new Rational(
numer * that.denom + that.numer * denom,
denom * that.denom
)
def + (i: Int): Rational =
new Rational(numer + i * denom, denom)
def - (that: Rational): Rational =
new Rational(
numer * that.denom - that.numer * denom,
denom * that.denom
)
def - (i: Int): Rational =
new Rational(numer - i * denom, denom)
def * (that: Rational): Rational =
new Rational(numer * that.numer, denom * that.denom)
def * (i: Int): Rational =
new Rational(numer * i, denom)
def / (that: Rational): Rational =
new Rational(numer * that.denom, denom * that.numer)
def / (i: Int): Rational =
new Rational(numer, denom * i)
override def toString = numer +"/"+ denom
private def gcd(a: Int, b: Int): Int =
if (b == 0) a else gcd(b, a % b)
override def equals(other: Any): Boolean =
other match {
case that: Rational =>
(that canEqual this) &&
numer == that.numer &&
denom == that.denom
case _ => false
}
def canEqual(other: Any): Boolean =
other.isInstanceOf[Rational]
override def hashCode: Int =
41 * (
41 + numer
) + denom
}
Scala
object Main {
def main(args: Array[String]) {
val x = new Rational(2, 3)
println("x [" + x + "]")
println("x * x [" + (x * x) + "]")
println("x * 2 [" + (x * 2) + "]")
implicit def intToRational(x: Int) = new Rational(x)
val r = new Rational(2,3)
println("2 * r [" + (2 * r) + "]")
}
}
Colecciones
Java 7 Fork Join Framework
Divide el trabajo por el número de Procesadores
Balance de granuralidad del overhead
Cada Thread tiene una Queue que se va ampliando exponencialmente
Mutables
Mayor distribución de carga
Scala
Easy to use
Concise
Safe
Fast
Scalable
Scala Actors
Sencillos
Muy buena integración con Threads
Son tanto bloqueantes como no bloqueantes
import scala.actors._
object FooActor extends Actor {
def act(){
for(i <- 1 to 11){
doSomething()
Thread.sleep(1000)
}
}
}
Scala Actors
val echoActor = actor {
while(true) {
receive {
case msg => println("Received message " + msg)
}
}
}
scala> echoActor ! "My First Message"
AKKA
Middleware basado en actores
Muy buena performance
Ampliamente escalable cluster y clouds
Safety
Akka
Ejemplo Chat
Play Framework
+
Scala
+
Akka
Clojure
Lenguaje dinámico de propósito general (JVM)
Es un dialecto de LISP
Scripting
Compila a byte code
Robusto
(defn fac-cps [n k]
(letfn [(cont [v] (k (* v n)))]
(if (zero? n)
(k 1)
(recur (dec n) cont))))
(defn factorial [n]
(fac-cps n identity))
Java vs Clojure
public class StringUtils {
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false {
return false;
}
}
return true;
}
}
Java vs Clojure
(defn blank? [str]
(every #((Character/isWhitespace %) str))
(defrecord Person [name age])
(def foo (->Person "Alex" 34))
Clojure
(defrecord Message [sender text])
(def messages (ref ()))
(def validate-message-list
(partial every? #(and (:sender %) (:text %))))
(def messages (ref () :validator validate-message-list))
(defn naive-add-message [msg]
(dosync (ref-set messages (cons msg @messages))))
(defn add-message [msg]
(dosync (alter messages conj msg)))
(defn add-message-commute [msg]
(dosync (commute messages conj msg)))
CLOJURE ASYNC
(ns sample (:require [http.async.client :as http]))
(with-open [client (http/create-client)]
(let [response (http/GET client "http://neotyk.github.com/http.async.client/")]
(-> response
http/await
http/string)))
Clojure Collections
(map (fn [x] (.toUpperCase x)) (.split "Dasher Dancer Prancer" " "))
(reduce + (r/map inc [1 2 3])) === (reduce (fn [ret x] (+ ret (inc x))) (+) [1 2 3])
fn * reducible -> reducible
Clojure
LISP mas recargado
Programación Funcional
Dynamic Development (REPL)
Next...
Lenguajes:
Programación Paralela + Universo de Datos
Ejemplo:
Twitter sobrevive a las elecciones de EEUU
31 Millon Tweets
Tweets per second (TPS)
9.965 TPS -> 8:11pm - 9:11pm
One-second Peek
15.107 TPS -> 8:20 pm
874.560 TPM
Ejemplo:
Twitter migración de Ruby a Java
Real Time Search Engine
Apache Lucene
Java Server Blender
Netty NIO
Ejemplo 2:
Scala
+
Play Framework
+
NoSQL
Gracias a todos...
@antiveroalejo
concurrencia y paralelismo
By aleantivero
concurrencia y paralelismo
- 238