View
1.983
Download
9
Category
Preview:
DESCRIPTION
Presentación realizada para la asignatura Arquitecturas Multiprocesador.
Citation preview
Paralelismo vs. Concurrencia
Roberto Costumero Moreno
Arquitecturas MultiprocesadorCurso 2011 / 2012
• Programas cada vez más complejos.
• Sistemas con múltiples CPUs multicore.
• Posibilidad de reducir el tiempo de ejecución de un programa.
Una visión general
Ventajas
• Menor tiempo de cómputo.
• Mayor aprovechamiento de los recursos.
• Permite en muchas tareas el acceso simultáneo de varios usuarios.
• Favorece una mayor cohesión y un menor acoplamiento entre las tareas a realizar.
Desventajas
• Mayor complejidad de los programas.
• Condiciones de carrera, ejecuciones no determinísticas...
• Mayor grado de especialización de los ingenieros.
• Código muy difícil de depurar.
¿Qué son la concurrencia y el
paralelismo?
• Concurrencia: Ejecución de programas de forma no determinística.
• Paralelismo: Explotación de la eficiencia de programas de forma determinística.
• Dos operaciones pueden estar realizándose en el mismo tiempo o no. Depende del paralelismo.
• Es necesaria para implementar paralelismo.
• Provee sistemas de sincronización y comunicación para programas ejecutados en una o más CPU.
Concurrencia
Paralelismo
• Implica la ejecución simultánea de dos o más operaciones en el mismo número de CPUs.
• Necesita de mecanismos de concurrencia para juntar las partes de los cálculos realizados.
¿Por qué es importante la concurrencia?
• Permite la simulación de una ejecución paralela en un entorno monocore.
• Gestiona el acceso seguro a elementos compartidos y secciones críticas.
• Garantiza que el resultado de las operaciones es siempre el mismo, independientemente del nº de threads.
¿Por qué es importante el paralelismo?
• Creciente número de cores en los ordenadores.
• Permite una gran disminución del tiempo de cómputo en programas de gran escala.
• Contribuye a un mayor aprovechamiento de los recursos.
Ejemplos
• Cálculo secuencial, concurrente (1 CPU) y paralelo (2 CPU) del número PI.
• Cálculo de la suma de los elementos de un vector de forma secuencial, concurrente y paralela.
PI secuencialpackage main
import ( "fmt" "math" "runtime")
func main() { runtime.GOMAXPROCS(1) fmt.Println(pi(100000))}
// pi launches n goroutines to compute an// approximation of pi.func pi(n int) float64 { f := 0.0 for k := 0; k <= n; k++ { f += term(float64(k)) } return f}
func term(k float64) float64 { return 4 * math.Pow(-1, k) / (2*k + 1)}
PI Concurrentepackage main
import ( "fmt" "math" "runtime")
func main() { runtime.GOMAXPROCS(1) fmt.Println(pi(100000))}
// pi launches n goroutines to compute an// approximation of pi.func pi(n int) float64 { ch := make(chan float64) for k := 0; k <= n; k++ { go term(ch, float64(k)) } f := 0.0 for k := 0; k <= n; k++ { f += <-ch } return f}
func term(ch chan float64, k float64) { ch <- 4 * math.Pow(-1, k) / (2*k + 1)}
PI Paralelopackage main
import ( "fmt" "math" "runtime")
func main() { runtime.GOMAXPROCS(2); fmt.Println(pi(100000))}
// pi launches n goroutines to compute an// approximation of pi.func pi(n int) float64 { ch := make(chan float64) for k := 0; k <= n; k++ { go term(ch, float64(k)) } f := 0.0 for k := 0; k <= n; k++ { f += <-ch } return f}
func term(ch chan float64, k float64) { ch <- 4 * math.Pow(-1, k) / (2*k + 1)}
Tiempos ejecución
3.1416026534897203 Secuencial Concurrente Paralelo
Real 0m0.032s
User 0m0.027s
Sys 0m0.002s
Tiempos ejecución
3.1416026534897203 Secuencial Concurrente Paralelo
Real 0m0.032s 0m0.689s
User 0m0.027s 0m0.333s
Sys 0m0.002s 0m0.347s
Tiempos ejecución
3.1416026534897203 Secuencial Concurrente Paralelo
Real 0m0.032s 0m0.689s 0m1.497s
User 0m0.027s 0m0.333s 0m0.493s
Sys 0m0.002s 0m0.347s 0m1.210s
Vector secuencialpackage main
import ( "fmt" "container/vector" "runtime")
func sum (v *vector.IntVector, n int) int { var total int = 0 for i := n; i < v.Len(); i += 4 { total += v.At(i) } return total}
func main () { runtime.GOMAXPROCS(1) var v *vector.IntVector = new (vector.IntVector) for i := 0; i < 100000000; i++ { v.Push(i) } var t int = 0 for i := 0; i < 4; i++ { t += sum (v, i) } fmt.Println(t)}
Vector Concurrenteimport ( "fmt" "container/vector" "runtime")
func sum (v *vector.IntVector, n int, ch chan int) { var total int = 0 for i := n; i < v.Len(); i += 4 { total += v.At(i) } ch <- total}
func main () { runtime.GOMAXPROCS(1) var v *vector.IntVector = new (vector.IntVector) for i := 0; i < 100000000; i++ { v.Push(i) } var t int = 0 ch := make(chan int) for i := 0; i < 4; i++ { go sum (v, i, ch) } for i := 0; i < 4; i++ { t += <-ch } fmt.Println(t)}
Vector Paraleloimport ( "fmt" "container/vector" "runtime")
func sum (v *vector.IntVector, n int, ch chan int) { var total int = 0 for i := n; i < v.Len(); i += 4 { total += v.At(i) } ch <- total}
func main () { runtime.GOMAXPROCS(2) var v *vector.IntVector = new (vector.IntVector) for i := 0; i < 100000000; i++ { v.Push(i) } var t int = 0 ch := make(chan int) for i := 0; i < 4; i++ { go sum (v, i, ch) } for i := 0; i < 4; i++ { t += <-ch } fmt.Println(t)}
Tiempos ejecución
887459712 Secuencial Concurrente Paralelo
Real 0m3.694s
User 0m3.031s
Sys 0m0.626s
Tiempos de inserción de elementos: real 0m2.716s || user 0m1.977s || sys 0m0.668s
Tiempos ejecución
887459712 Secuencial Concurrente Paralelo
Real 0m3.694s 0m3.725s
User 0m3.031s 0m3.068s
Sys 0m0.626s 0m0.632s
Tiempos de inserción de elementos: real 0m2.716s || user 0m1.977s || sys 0m0.668s
Tiempos ejecución
887459712 Secuencial Concurrente Paralelo
Real 0m3.694s 0m3.725s 0m3.179s
User 0m3.031s 0m3.068s 0m3.025s
Sys 0m0.626s 0m0.632s 0m0.638s
Tiempos de inserción de elementos: real 0m2.716s || user 0m1.977s || sys 0m0.668s
• http://existentialtype.wordpress.com/2011/03/17/parallelism-is-not-concurrency/
• http://existentialtype.wordpress.com/2011/03/15/teaching-fp-to-freshmen/
• http://ghcmutterings.wordpress.com/2009/10/06/parallelism-concurrency/
• http://my.opera.com/Vorlath/blog/2009/10/08/parallel-vs-concurrent
• http://golang.org
Bibliografía
Recommended