Práctica 3. Generación de números primos
|
|
|
- Santiago Campos Montero
- hace 7 años
- Vistas:
Transcripción
1 Práctica 3 Generación de números primos Septiembre-Diciembre 2007
2 1 Algoritmo secuencial (primosec) En esta práctica vamos a trabajar con la generación de números primos basado en el método conocido como la criba de Eratóstenes. En nuestro ejemplo, se maneja una tabla con los primeros 480 números primos (del 3 al incluidos, ya que excluimos el 1 y el 2) que nos permitirá calcular primos por debajo de que es el cuadrado de (dos más del último primo conocido y del que no se puede asegurar que sea o no primo, aunque en este caso sea obvio que no lo es). El programa desarrollado admite un parámetro de línea de comando que permite fijar con cuántos primos conocidos vamos a trabajar, para así poder hacer varias pruebas sin necesidad de recompilar. Gráficamente, este algoritmo puede expresarse de la forma siguiente: ,...,3437,3435 primosec [ ] ,...,3457,3449 Tabla de primeros primos conocidos En este apartado se va a probar la ejecución del algoritmo secuencial primosec.c cuyo código se suministra totalmente escrito y se muestra a continuación: #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #define TRUE 1 #define FALSE 0 Secuencia de números por los que probar (impares < ) #define TOT_PRIMOS_CONOCIDOS 480 Secuencia de números primos calculados static int primosconocidos[tot_primos_conocidos] = 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, Práctica 3: Generación de números primos Página - 1
3 ; 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,1009,1013,1019, 1021,1031,1033,1039,1049,1051,1061,1063,1069,1087, 1091,1093,1097,1103,1109,1117,1123,1129,1151,1153, 1163,1171,1181,1187,1193,1201,1213,1217,1223,1229, 1231,1237,1249,1259,1277,1279,1283,1289,1291,1297, 1301,1303,1307,1319,1321,1327,1361,1367,1373,1381, 1399,1409,1423,1427,1429,1433,1439,1447,1451,1453, 1459,1471,1481,1483,1487,1489,1493,1499,1511,1523, 1531,1543,1549,1553,1559,1567,1571,1579,1583,1597, 1601,1607,1609,1613,1619,1621,1627,1637,1657,1663, 1667,1669,1693,1697,1699,1709,1721,1723,1733,1741, 1747,1753,1759,1777,1783,1787,1789,1801,1811,1823, 1831,1847,1861,1867,1871,1873,1877,1879,1889,1901, 1907,1913,1931,1933,1949,1951,1973,1979,1987,1993, 1997,1999,2003,2011,2017,2027,2029,2039,2053,2063, 2069,2081,2083,2087,2089,2099,2111,2113,2129,2131, 2137,2141,2143,2153,2161,2179,2203,2207,2213,2221, 2237,2239,2243,2251,2267,2269,2273,2281,2287,2293, 2297,2309,2311,2333,2339,2341,2347,2351,2357,2371, 2377,2381,2383,2389,2393,2399,2411,2417,2423,2437, 2441,2447,2459,2467,2473,2477,2503,2521,2531,2539, 2543,2549,2551,2557,2579,2591,2593,2609,2617,2621, 2633,2647,2657,2659,2663,2671,2677,2683,2687,2689, 2693,2699,2707,2711,2713,2719,2729,2731,2741,2749, 2753,2767,2777,2789,2791,2797,2801,2803,2819,2833, 2837,2843,2851,2857,2861,2879,2887,2897,2903,2909, 2917,2927,2939,2953,2957,2963,2969,2971,2999,3001, 3011,3019,3023,3037,3041,3049,3061,3067,3079,3083, 3089,3109,3119,3121,3137,3163,3167,3169,3181,3187, 3191,3203,3209,3217,3221,3229,3251,3253,3257,3259, 3271,3299,3301,3307,3313,3319,3323,3329,3331,3343, 3347,3359,3361,3371,3373,3389,3391,3407,3413,3433 int main (int argc, char **argv) struct timeval t0, t1, t; int numprimosconocidos; int total = 0; int siguiente; // Siguiente numero de la serie a cribar int cotaserie; // Cota superior hasta donde van a determinarse // numeros primos con los ya conocidos int esprimo (int numero) int i; for (i=0; i<numprimosconocidos; i++) if ((numero % primosconocidos[i]) == 0) return FALSE; return TRUE; // Control del parametro de linea de comandos if (argc!= 2) printf ("Uso: primosec numprimosconocidos \n"); return 0; Práctica 3: Generación de números primos Página - 2
4 numprimosconocidos = atoi(argv[1]); assert (numprimosconocidos > 0); assert (numprimosconocidos <= TOT_PRIMOS_CONOCIDOS); assert (gettimeofday (&t0, NULL) == 0); siguiente = primosconocidos[numprimosconocidos-1]+2; cotaserie = siguiente * siguiente; while (siguiente < cotaserie) if (esprimo(siguiente)) // Comentar los dos printf del if en la version sin E/S printf ("%9i", siguiente); // Comentar total++; if ((total%10) == 0) printf ("\n"); // Comentar siguiente = siguiente + 2; assert (gettimeofday (&t1, NULL) == 0); timersub(&t1, &t0, &t); printf ("\nprimos calculados => %6i\n", total); printf ("Tiempo => %ld:%ld(seg:mseg)\n", t.tv_sec, t.tv_usec/1000); return 0; Generar el ejecutable de primosec.c Ejecutar varias veces este comando con distintos valores de número de primos conocidos y rellenar lo que corresponda de la Tabla-1 de tiempos. Volver a generar el ejecutable de primosec, pero anulando la escritura de los números primos y volver a tomar tiempos rellenando las casillas correspondientes de la Tabla- 1. Observar que el tiempo gastado en imprimir por pantalla es elevado. 2 Un modelo paralelo (primopar1) Si disponemos de dos procesadores, podemos hacer que cada uno de ellos (dispuestos en pipeline ) ejecute una variante del programa secuencial de la sección anterior. El primer filtro de la cadena aplicará el test de divisibilidad con la mitad de los primeros números primos conocidos (del 3 al inclusive). Los números que no hayan sido divididos por estos primeros 240 primos, se los pasará al siguiente filtro, que realizará el test de divisibilidad con la otra mitad de primos conocidos (del al inclusive). Este modelo, sin retoques, es generalizable para 4, 6, 8 10, 12 y 16 procesadores ya que la tabla de primos conocidos admite particiones exactas al ser 480 múltiplo del número de procesadores. Gráficamente el modelo es el siguiente: Práctica 3: Generación de números primos Página - 3
5 ,...,3437,3435 Filtro0 Filtro ,...,3457,3449 [ ] 240 [ ] 240 Secuencia de números por los que probar (impares < ) Secuencia de números primos calculados Este programa paralelo no tendrá parámetros de línea de comando, ya que el número de primos conocidos con los que se va a trabajar se fija en 240. Al arrancar n procesos MPI, todos ellos sabrán quiénes son (0, 1, 2,, n-1) y cuántos procesos hay (n), pudiendo determinar con qué trozo de la tabla de primos conocidos debe trabajar cada uno de los procesos. Si nos fijamos más adelante en el código, veremos que podríamos haber hecho una optimización en el sentido de no enviar del Filtro0 al Filtro1 los números menores que ( ) y que no hayan sido divididos por Filtro0, ya que sabemos con certeza que son números primos. No obstante, esta optimización no está hecha en el programa primosec (con el objetivo de simplificar el código), por lo que tampoco la haremos en la versión paralela. El código definitivo del programa primopar1.c es el siguiente: #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/time.h> #include "mpi.h" #define TRUE 1 #define FALSE 0 #define MAX_PRIMOS_CONOCIDOS 480 // Maximo de la tabla #define NUM_PRIMOS_CONOCIDOS 240 // Primos con los que probar #define MAX_PROCESOS 16 static int primosconocidos[max_primos_conocidos] = 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, Práctica 3: Generación de números primos Página - 4
6 ; 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,1009,1013,1019, 1021,1031,1033,1039,1049,1051,1061,1063,1069,1087, 1091,1093,1097,1103,1109,1117,1123,1129,1151,1153, 1163,1171,1181,1187,1193,1201,1213,1217,1223,1229, 1231,1237,1249,1259,1277,1279,1283,1289,1291,1297, 1301,1303,1307,1319,1321,1327,1361,1367,1373,1381, 1399,1409,1423,1427,1429,1433,1439,1447,1451,1453, 1459,1471,1481,1483,1487,1489,1493,1499,1511,1523, 1531,1543,1549,1553,1559,1567,1571,1579,1583,1597, 1601,1607,1609,1613,1619,1621,1627,1637,1657,1663, 1667,1669,1693,1697,1699,1709,1721,1723,1733,1741, 1747,1753,1759,1777,1783,1787,1789,1801,1811,1823, 1831,1847,1861,1867,1871,1873,1877,1879,1889,1901, 1907,1913,1931,1933,1949,1951,1973,1979,1987,1993, 1997,1999,2003,2011,2017,2027,2029,2039,2053,2063, 2069,2081,2083,2087,2089,2099,2111,2113,2129,2131, 2137,2141,2143,2153,2161,2179,2203,2207,2213,2221, 2237,2239,2243,2251,2267,2269,2273,2281,2287,2293, 2297,2309,2311,2333,2339,2341,2347,2351,2357,2371, 2377,2381,2383,2389,2393,2399,2411,2417,2423,2437, 2441,2447,2459,2467,2473,2477,2503,2521,2531,2539, 2543,2549,2551,2557,2579,2591,2593,2609,2617,2621, 2633,2647,2657,2659,2663,2671,2677,2683,2687,2689, 2693,2699,2707,2711,2713,2719,2729,2731,2741,2749, 2753,2767,2777,2789,2791,2797,2801,2803,2819,2833, 2837,2843,2851,2857,2861,2879,2887,2897,2903,2909, 2917,2927,2939,2953,2957,2963,2969,2971,2999,3001, 3011,3019,3023,3037,3041,3049,3061,3067,3079,3083, 3089,3109,3119,3121,3137,3163,3167,3169,3181,3187, 3191,3203,3209,3217,3221,3229,3251,3253,3257,3259, 3271,3299,3301,3307,3313,3319,3323,3329,3331,3343, 3347,3359,3361,3371,3373,3389,3391,3407,3413,3433 static int iprimoinicial, iprimofinal; int divisible (int numero) int i; for (i=iprimoinicial; i<=iprimofinal; i++) if ((numero % primosconocidos[i]) == 0) return TRUE; return FALSE; void enviar (int proceso, int numero) MPI_Send (&numero, 1, MPI_INT, proceso, 1, MPI_COMM_WORLD); void recibir (int proceso, int *numero) MPI_Status estado; MPI_Recv (numero, 1, MPI_INT, proceso, 1, MPI_COMM_WORLD, &estado); Práctica 3: Generación de números primos Página - 5
7 void filtrocero (int numprocesos) struct timeval t0, t1, t; int numero, cotaserie; int miderecha = 1, numprimosporproceso; assert (gettimeofday (&t0, NULL) == 0); numprimosporproceso = NUM_PRIMOS_CONOCIDOS / numprocesos; iprimoinicial = 0; iprimofinal = numprimosporproceso-1; numero = primosconocidos[num_primos_conocidos-1]+2; cotaserie = numero * numero; while (numero < cotaserie) if (!divisible(numero)) enviar(miderecha, numero); numero = numero + 2; enviar(miderecha, 0); recibir(numprocesos-1, &numero); // Indicacion de terminacion assert (gettimeofday (&t1, NULL) == 0); timersub(&t1, &t0, &t); printf ("Tiempo => %ld:%ld(seg:mseg)\n", t.tv_sec, t.tv_usec/1000); void filtronocero (int numprocesos, int yo) int numero, miizquierda, miderecha=0, soyelultimo; int numprimosporproceso, totalprimos=0; miizquierda = yo-1; soyelultimo = (yo == (numprocesos-1)); if (! soyelultimo) miderecha = yo+1; numprimosporproceso = NUM_PRIMOS_CONOCIDOS / numprocesos; iprimoinicial = yo * numprimosporproceso; iprimofinal = iprimoinicial + numprimosporproceso - 1; recibir(miizquierda, &numero); while (numero!= 0) if (!divisible(numero)) if (soyelultimo) //descomentar los dos printf del if si se desea ver la salida //printf("%8i", numero); // Descomentar totalprimos++; //if ((totalprimos%10) == 0) printf("\n"); // Descomentar else enviar(miderecha, numero); recibir(miizquierda, &numero); if (soyelultimo) printf ("\nprimos calculados => %6i\n", totalprimos); enviar(0, 0); else enviar(miderecha, numero); // Propagar indicacion terminacion Práctica 3: Generación de números primos Página - 6
8 int main (int argc, char **argv) int numprocesos, yo; char nombrepc[100]; setbuf (stdout, NULL); MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &yo); MPI_Comm_size (MPI_COMM_WORLD, &numprocesos); gethostname (nombrepc, 100); printf ( Proceso %d ejecutandose en %s\n, yo, nombrepc); if (yo == 0) assert ((numprocesos > 1) && (numprocesos <= MAX_PROCESOS)); assert (numprocesos!= 14); assert ((numprocesos % 2) == 0); filtrocero(numprocesos); else filtronocero(numprocesos, yo); MPI_Finalize(); return 0; Generar el ejecutable de primopar1.c Probar la ejecución de primopar1 variando el número de procesos. Observar cómo se comporta en comparación con la versión secuencial. Para comprender todavía más el funcionamiento de esta versión puede modificarse el programa para que informe la cantidad de números que se pasan del filtro 0 al 1, del filtro 1 al 2 y del filtro 2 al 3. También podemos hacer esta misma prueba para cuando ejecutamos con tan sólo dos filtros y ver el volumen de información que se pasa de un filtro al otro. Los datos serán muy reveladores. 3 Un modelo paralelo eficiente (primopar2) La ineficiencia del modelo anterior viene del elevado número de comunicaciones pequeñas que se producen en comparación con los cálculos que se realizan. Una forma de suavizar este problema es hacer buffer de los números que se van transfiriendo los filtros, de forma que las comunicaciones reales entre dichos filtros sean de mensajes de 100 números. El código definitivo del programa primopar2.c es el siguiente: #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include "mpi.h" #define TRUE 1 Práctica 3: Generación de números primos Página - 7
9 #define FALSE 0 #define MAX_PRIMOS_CONOCIDOS 480 // Maximo de la tabla #define NUM_PRIMOS_CONOCIDOS 480 // Primos con los que trabajar #define MAX_PROCESOS 16 #define MAX_MAQUINAS 8 #define LONG_BUFFER 100 typedef struct buffer int numeros[long_buffer]; int cuantos; int actual; // Para buffer de entrada buffer_t; static int primosconocidos[max_primos_conocidos] = 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,1009,1013,1019, 1021,1031,1033,1039,1049,1051,1061,1063,1069,1087, 1091,1093,1097,1103,1109,1117,1123,1129,1151,1153, 1163,1171,1181,1187,1193,1201,1213,1217,1223,1229, 1231,1237,1249,1259,1277,1279,1283,1289,1291,1297, 1301,1303,1307,1319,1321,1327,1361,1367,1373,1381, 1399,1409,1423,1427,1429,1433,1439,1447,1451,1453, 1459,1471,1481,1483,1487,1489,1493,1499,1511,1523, 1531,1543,1549,1553,1559,1567,1571,1579,1583,1597, 1601,1607,1609,1613,1619,1621,1627,1637,1657,1663, 1667,1669,1693,1697,1699,1709,1721,1723,1733,1741, 1747,1753,1759,1777,1783,1787,1789,1801,1811,1823, 1831,1847,1861,1867,1871,1873,1877,1879,1889,1901, 1907,1913,1931,1933,1949,1951,1973,1979,1987,1993, 1997,1999,2003,2011,2017,2027,2029,2039,2053,2063, 2069,2081,2083,2087,2089,2099,2111,2113,2129,2131, 2137,2141,2143,2153,2161,2179,2203,2207,2213,2221, 2237,2239,2243,2251,2267,2269,2273,2281,2287,2293, 2297,2309,2311,2333,2339,2341,2347,2351,2357,2371, 2377,2381,2383,2389,2393,2399,2411,2417,2423,2437, 2441,2447,2459,2467,2473,2477,2503,2521,2531,2539, 2543,2549,2551,2557,2579,2591,2593,2609,2617,2621, 2633,2647,2657,2659,2663,2671,2677,2683,2687,2689, 2693,2699,2707,2711,2713,2719,2729,2731,2741,2749, 2753,2767,2777,2789,2791,2797,2801,2803,2819,2833, 2837,2843,2851,2857,2861,2879,2887,2897,2903,2909, 2917,2927,2939,2953,2957,2963,2969,2971,2999,3001, 3011,3019,3023,3037,3041,3049,3061,3067,3079,3083, 3089,3109,3119,3121,3137,3163,3167,3169,3181,3187, 3191,3203,3209,3217,3221,3229,3251,3253,3257,3259, Práctica 3: Generación de números primos Página - 8
10 ; 3271,3299,3301,3307,3313,3319,3323,3329,3331,3343, 3347,3359,3361,3371,3373,3389,3391,3407,3413,3433 static int iprimoinicial, iprimofinal; int divisible (int numero) int i; for (i=iprimoinicial; i<=iprimofinal; i++) if ((numero % primosconocidos[i]) == 0) return TRUE; return FALSE; void enviar (int proceso, int numero) MPI_Send (&numero, 1, MPI_INT, proceso, 1, MPI_COMM_WORLD); void recibir (int proceso, int *numero) MPI_Status estado; MPI_Recv (numero, 1, MPI_INT, proceso, 1, MPI_COMM_WORLD, &estado); void enviarbuffer (buffer_t *b, int proceso, int numero) b->numeros[b->cuantos] = numero; if (b->cuantos == (LONG_BUFFER-1)) MPI_Send (b->numeros,long_buffer, MPI_INT, proceso, 1,MPI_COMM_WORLD); b->cuantos = 0; else b->cuantos++; void vaciarbuffer (buffer_t *b, int proceso) if (b->cuantos > 0) MPI_Send (b->numeros, b->cuantos, MPI_INT, proceso, 1, MPI_COMM_WORLD); b->cuantos = 0; void recibirbuffer (buffer_t *b, int proceso, int *numero) MPI_Status estado; if (b->actual == b->cuantos) MPI_Recv (b->numeros, LONG_BUFFER, MPI_INT, proceso, 1, MPI_COMM_WORLD, &estado); MPI_Get_count (&estado, MPI_INT, &(b->cuantos)); b->actual = 0; *numero = b->numeros[b->actual++]; Práctica 3: Generación de números primos Página - 9
11 void filtrocero (int numprocesos, int yo) struct timeval t0, t1, t; int numero, cotaserie; int miderecha = 1, numprimosporproceso; buffer_t salida; assert (gettimeofday (&t0, NULL) == 0); numprimosporproceso = NUM_PRIMOS_CONOCIDOS / numprocesos; iprimoinicial = 0; iprimofinal = iprimoinicial + numprimosporproceso - 1; numero = primosconocidos[num_primos_conocidos-1]+2; cotaserie = numero * numero; salida.cuantos = 0; while (numero < cotaserie) if (!divisible(numero)) enviarbuffer (&salida, miderecha, numero); numero = numero + 2; enviarbuffer(&salida, miderecha, 0); vaciarbuffer(&salida, miderecha); recibir(mpi_any_source, &numero); // Indicacion de terminacion assert (gettimeofday (&t1, NULL) == 0); timersub(&t1, &t0, &t); printf ("Tiempo => %ld:%ld(seg:mseg)\n", t.tv_sec, t.tv_usec/1000); void filtronocero (int numprocesos, int yo) int numero, miizquierda, miderecha=0, soyelultimo; int numprimosporproceso, totalprimos=0; buffer_t entrada, salida; miizquierda = yo-1; soyelultimo = (yo == (numprocesos-1)); if (! soyelultimo) miderecha = yo+1; numprimosporproceso = NUM_PRIMOS_CONOCIDOS / numprocesos; iprimoinicial = yo * numprimosporproceso; iprimofinal = iprimoinicial + numprimosporproceso - 1; entrada.cuantos = 0; entrada.actual = 0; salida.cuantos = 0; recibirbuffer(&entrada, miizquierda, &numero); while (numero!= 0) if (!divisible(numero)) if (soyelultimo) //Descomentar los dos printf del if para ver la salida //printf("%8i", numero); //Descomentar totalprimos++; //if ((totalprimos%10) == 0) printf("\n"); //Descomentar else enviarbuffer(&salida, miderecha, numero); recibirbuffer(&entrada, miizquierda, &numero); if (soyelultimo) printf ("\nprimos calculados => %6i\n", totalprimos); enviar(0, 0); else enviarbuffer(&salida, miderecha, numero); // Propagar terminacion vaciarbuffer(&salida, miderecha); Práctica 3: Generación de números primos Página - 10
12 int main (int argc, char **argv) int yo, numprocesos; setbuf (stdout, NULL); MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &yo); MPI_Comm_size (MPI_COMM_WORLD, &numprocesos); if (yo == 0) assert ((numprocesos > 1) && (numprocesos <= MAX_PROCESOS)); assert (numprocesos!= 14); assert ((numprocesos % 2) == 0); filtrocero(numprocesos, yo); else filtronocero(numprocesos, yo); MPI_Finalize(); return 0; Generar el ejecutable de primopar2.c Probar la ejecución de primopar2 rellenando la Tabla-3 4 Modelo paralelo alternativo a desarrollar (primopar3) En este apartado se trata de escribir una versión paralela que calcule primos con mayor eficiencia que el modelo de pipeline. La idea es que los filtros tengan, cada uno, la tabla completa de primos conocidos y trabajen con todos ellos, pero repartiéndose la serie de números impares que van a ser sometidos al test de divisibilidad. Gráficamente, para el caso de dos filtros, sería lo siguiente: Filtro0 [ ] ,...,3437,3435 Secuencia de números primos calculados Filtro1 Secuencia de números por los que probar (impares < ) [ ] 480 Una forma de dividir la serie de entrada es que el filtro cero tome los números 3435, 3439, 3443 y así sucesivamente, mientras que el filtro uno tome el resto, es decir, los números 3437, 3441, 3445 etc. Práctica 3: Generación de números primos Página - 11
13 Con este modelo, la secuencia de números primos saldrá desordenada si cada filtro imprime sus primos según los va calculando. Opcionalmente, se puede intentar mejorar el modelo para que los números primos salgan ordenados, tal y como sucedía en el caso de las versiones secuencial y paralela de las secciones anteriores ojo, es más difícil-. Se puede partir del programa primopar1.c como esqueleto. Se sugiere fundir filtrocero y filtronocero en un único filtro (ejecutado por todos los procesos) que reciba los parámetros necesarios para que pueda determinar con qué parte de la serie de números de entrada va a trabajar. Además, todos los procesos filtros del 1 en adelante, informarán al proceso maestro (el 0) del número de primos que han calculado. El proceso maestro concluirá indicando el tiempo empleado y el número total de primos que han calculado entre todos los filtros (incluido él mismo). Una vez escrito, compilado y depurado el programa, rellenar la Tabla-4 (columnas de tiempos y eficiencia) y comparar los resultados obtenidos respecto de los de la Tabla-3 (programa primopar2). Una mínima comprobación de que el programa es correcto puede consistir en constatar que esta versión informa del mismo número total de primos que en las versiones anteriores. Si llega a observar algo extraño con la eficiencia para el caso de 6, 10 y 12 procesos, modifique el programa para que informe de la cantidad de divisiones que realiza cada proceso y anotar las columnas de MínDivisiones y MáxDivisiones de la Tabla-4. Práctica 3: Generación de números primos Página - 12
14 Tabla-1. Tiempos de la versión primosec primosconocidos primoscalculados Tiempo (con E/S) Tiempo (sin E/S) Tabla-2. Tiempos de la versión primopar1 (con 240 primosconocidos) numprocesos Tiempo (seg:mseg) Tabla-3. Tiempos de la versión primopar2 (con 480 primosconocidos) numprocesos Tiempo (seg:mseg) Eficiencia Tabla-4. Tiempos de la versión primopar3 (con 480 primosconocidos) numprocesos Tiempo (seg:mseg) Eficiencia MínDivisiones MáxDivisiones Práctica 3: Generación de números primos Página - 13
1 Primitivas básicas de OpenMP
1 Primitivas básicas de OpenMP Consultar la página oficial de la plataforma OpenMP http://www.openmp.org/drupal/ Pragmas Es una directiva para el compilador que permite la definición de nuevas directivas
MPI Introducción Procesos Envío y recepción simple Envío y recepción no tan simple Comunicación colectiva. Herramientas de depuración y evaluación
Tutorial sobre MPI Temario 1 MPI Introducción Procesos Envío y recepción simple Envío y recepción no tan simple Comunicación colectiva Herramientas de depuración y evaluación arqavapar MPI (Introducción)
ETSISI - UPM Procesamiento Paralelo Curso 18/19. Práctica 2. Método de Monte Carlo y Superaceleración
Práctica 2 Método de Monte Carlo y Superaceleración 2 de Octubre 2018 ÍNDICE 1 Objetivos... 2 2 El método de Monte Carlo aplicado al cálculo de PI... 2 2.1 El método... 2 2.2 Tres versiones secuenciales...
Message Passing Interface (MPI)
Message Passing Interface (MPI) INTRODUCCIÓN MPI (Message Passing Interface) como es un interfaz estandarizada para la realización de aplicaciones paralelas basadas en pasaje de mensajes. El modelo de
Toma de contacto con MPI
Toma de contacto con MPI Práctica 0: Toma de contacto con MPI Página - 0 ÍNDICE 1 Visión global de MPI...2 2 Primitivas básicas de MPI para crear procesos y comunicarse entre ellos...3 2.1 Control de procesos...3
Paradigma de paso de mensajes
Paradigma de paso de mensajes Curso 2011-2012 Índice Visión lógica del paradigma de paso de mensajes. Operaciones básicas en paso de mensajes. Operaciones bloqueantes. Operaciones no bloqueantes. MPI:
Enunciado 2 Descifrar claves cifradas con crypt
Enunciado 2 Descifrar claves cifradas con crypt INDICE 1 Definición del problema...1 2 Solución secuencial...1 3 Tabla de tiempos...3 4 Para saber más...3 5 Listado de programas...3 5.1 cifrado.h...4 5.2
Práctica 1. Primera experiencia con MPI
Práctica 1 Primera experiencia con MPI Septiembre-Diciembre 2008 ÍNDICE 1 VISIÓN GLOBAL DE MPI... 2 2 PRIMITIVAS BÁSICAS DE MPI PARA CREAR PROCESOS Y COMUNICACIÓN... 3 2.1 CONTROL DE PROCESOS... 4 2.2
Master SIA. Programación de Sistemas Paralelos. MPI: Ejercicios prácticos. Ejercicio 1. Facultad de Informática
Master SIA Facultad de Informática Programación de Sistemas Paralelos MPI: Ejercicios prácticos Te proponemos realizar estos cuatro ejercicios. Al final, y junto con los ejercicios sobre OpenMP, hay que
Procesamiento Paralelo
Procesamiento Paralelo Introducción a MPI Javier Iparraguirre Universidad Tecnológica Nacional, Facultad Regional Bahía Blanca 11 de Abril 461, Bahía Blanca, Argentina [email protected] http://www.frbb.utn.edu.ar/hpc/
SISTEMAS PARALELOS Y DISTRIBUIDOS. 3º GIC. PRÁCTICA 9 Departamento de Arquitectura y Tecnología de Computadores Universidad de Sevilla
SISTEMAS PARALELOS Y DISTRIBUIDOS. 3º GIC. PRÁCTICA 9 Departamento de Arquitectura y Tecnología de Computadores Universidad de Sevilla PROGRAMACIÓN DE COMPUTADORES DE MEMORIA DISTRIBUIDA USANDO MPI. PREPARACIÓN
ETSISI-UPM Arquitecturas Avanzadas Paralelas Curso 17/18. Toma de contacto con la placa Parallella Epiphany-16 Lab4401 y Lab4405
Toma de contacto con la placa Parallella Epiphany-16 Lab4401 y Lab4405 Marzo 2018 ÍNDICE 1 Visión global de la placa... 2 2 Primitivas básicas para comunicación entre Host y Epiphany... 6 2.1 Configuración
Programación en Entornos Paralelos: MPI
1-11 Marzo de 2017 FACET -UNT Programación en Entornos Paralelos: MPI Graciela Molina mgracielamolina@gmailcom TRADICIONALMENTE Procesamiento secuencial 2 TRADICIONALMENTE Procesamiento secuencial Si ya
MPI es un estándar de programación en paralelo mediante paso de mensajes que permite crear programas portables y eficientes.
Programación paralela en MPI MPI es un estándar de programación en paralelo mediante paso de mensajes que permite crear programas portables y eficientes. Introducción a MPI MPI fue creado en 1993 como
SESIÓN DE EJERCICIOS E1
SESIÓN DE EJERCICIOS E1 Primera parte: ejercicios test (soluciones al final) A resolver antes de comenzar la sesión en el aula Ejercicio 1 Qué definición de constantes es la correcta en lenguaje C? a)
Programación I Funciones
1 Funciones Iván Cantador 2 Funciones: definición, sintaxis, ejemplos (I) Una funciónes un bloque de sentencias identificado con un nombre que se ejecutan de manera secuencial ofreciendo una funcionalidad
INTRODUCCIÓN A LA PROGRAMACIÓN DE COMPUTADORES DE MEMORIA DISTRIBUIDA USANDO MPI SISTEMAS PARALELOS Y DISTRIBUIDOS
INTRODUCCIÓN A LA PROGRAMACIÓN DE COMPUTADORES DE MEMORIA DISTRIBUIDA USANDO MPI 1 Y DISTRIBUIDOS GRADO EN INGENIERÍA INFORMÁTICA INGENIERÍA DE COMPUTADORES ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA
Introducción a Sistemas Operativos: Ficheros
Introducción a Sistemas Operativos: Ficheros Clips Fr ancisco J Ballesteros 1. Entrada/Salida Es importante saber cómo utilizar ficheros. En UNIX, es aún más importante dado que gran parte de los recursos,
Repaso Lenguaje C Área de Servicios Programación (Ing. Elect. y Prof. Tec.), Programación I (TUG y TUR) y Electrónica programable (TUE)
Repaso Lenguaje C OBJETOS Variables Constantes Variable: objeto del ambiente cuyo contenido puede cambiar. Constante: objeto cuyo contenido no puede cambiar. Variables: - un nombre que la identifica. Deben
Realizar el ejercicio anterior utilizando Punteros
PUNTEROS Y ARRAYS En C existe una relación entre punteros y arrays tal que cualquier operación que se pueda realizar mediante la indexación de un arrays, se puede realizar también con punteros. Para clarificar
UNIVERSIDAD CARLOS III DE MADRID DEPARTAMENTO DE INFORMÁTICA INGENIERÍA EN INFORMÁTICA. ARQUITECTURA DE COMPUTADORES II 19 de junio de 2007
UNIVERSIDAD CARLOS III DE MADRID DEPARTAMENTO DE INFORMÁTICA INGENIERÍA EN INFORMÁTICA. ARQUITECTURA DE COMPUTADORES II 19 de junio de 2007 Para la realización del presente examen se dispondrá de 2 1/2
Tema 3. Estructuras de control
Tema 3. Estructuras de control 3.1. Secuencial 3.2. Selección 3.3. Repetición 2 Objetivos Objetivos del tema: Conocer y saber la utilidad de las tres estructuras de control (secuencial, alternativa y repetitiva)
Multiprocesamiento en lenguaje C Introducción a MPI
Multiprocesamiento en lenguaje C Introducción a MPI Message Passing Interface Pertinencia de la enseñanza del cómputo paralelo en el currículo de las ingenierías MPI MPI es un estándar de programación
Ejercicios sobre tuberías
Boletín 3. Ejercicios sobre tuberías July 14, 016 1. Indica de manera justificada si las siguientes afirmaciones sobre la utilización de tuberías como mecanismo de sincronización entre dos procesos son
Procesamiento Paralelo
Procesamiento Paralelo MPI - Tipos y Topologías Javier Iparraguirre Universidad Tecnológica Nacional, Facultad Regional Bahía Blanca 11 de Abril 461, Bahía Blanca, Argentina [email protected]
SESIÓN DE EJERCICIOS E1
SESIÓN DE EJERCICIOS E1 Primera parte: ejercicios test Ejercicio 1 Qué definición de constantes es la correcta en lenguaje C? a) #define N=25; b) #define N 25 c) int N=25; d) int N 25 Ejercicio 2 La expresión
Estructura de Datos L I S T A
Estructura de Datos TDA L I S T A El TDA Lista El TDA Lista es una estructura compuesta por nodos (en los cuales se encuentran los datos almacenados) los cuales se encuentran enlazados entre si uno a uno
Codificación en C. Como pasar de Pseudocódigo a C (con pequeños trucos de C++)
Codificación en C Como pasar de Pseudocódigo a C (con pequeños trucos de C++) Plantilla Librerias Constantes Algoritmo #include #include #define PI 3.1416 int main(void){ /*Variables*/
EJERCICIOS CON FUNCIONES EN C. EJEMPLO CALCULAR SERIES NUMÉRICAS. REFACTORIZAR. (CU00552F)
APRENDERAPROGRAMAR.COM EJERCICIOS CON FUNCIONES EN C. EJEMPLO CALCULAR SERIES NUMÉRICAS. REFACTORIZAR. (CU00552F) Sección: Cursos Categoría: Curso básico de programación en lenguaje C desde cero Fecha
Lenguaje C. República Bolivariana de Venezuela Fundación Misión Sucre Aldea Fray Pedro de Agreda Introducción a la Programación III
República Bolivariana de Venezuela Fundación Misión Sucre Aldea Fray Pedro de Agreda Introducción a la Programación III Lenguaje C 1 Puntos previos Los códigos fuentes generados en C requieren ser compilados
1. Presentación del lenguaje C Creado en 1972 por D. Ritchie Lenguaje de propósito general Portátil o transportable (generalmente) Inicialmente de niv
Introducción al lenguaje C Informática Belarmino Pulido Junquera Índice 1. Presentación del lenguaje C 2. Estructura de un programa en C 3. Instrucciones del pre-procesador procesador 4. Tipos de datos
Biblioteca de sistema
* Para la realización del presente examen se aconseja un tiempo de 2 horas. Teoría 1. Explique en detalle cómo se pasa una llamada al sistema operativo. El sistema operativo se activa cuando debe responder
for(i = 0; i <= 45; i+=5) { x = (i*3.1416)/180; printf( seno(%d) = %f\n,i,seno(x));
Ejemplo #include #include float seno(float x); int main(){ int i; float x; for(i = 0; i
Estructuras de Decisión Simples y Dobles
Estructuras de Decisión Simples y Dobles 1 Estructuras no secuenciales Los programas que hemos escrito hasta ahora han consistido en una serie de sentencias que se ejecutan secuencialmente, una después
Introducción general al Lenguaje C (2010/2011)
Luis Valencia Cabrera [email protected] (http://www.cs.us.es/~lvalencia) Ciencias de la Computacion e IA (http://www.cs.us.es/) Introducción general al Lenguaje C (2010/2011) Universidad de Sevilla Índice
1000+(4/100)*1000 =1000 * (1+4/100) =1000 * 1.04 = Al finalizar el segundo año, el 4% se aplica sobre los 1040, y obtenemos:
Nombre: Apellidos: Grupo: Nº. Matrícula Ejercicio 1 (2,5 puntos 30 minutos) Al ingresar capital en un banco, pongamos 1000, éste nos ofrece un porcentaje anual de interés, por ejemplo el 4%. Al cabo de
Tema ADQUISICIÓN Y TRATAMIENTO DE DATOS. Departamento de Ciencias de la Computación e IA. Subprogramas en C
Tema ADQUISICIÓN Y TRATAMIENTO DE DATOS Departamento de Ciencias de la Computación e IA Subprogramas en C Objetivo Una vez que tengamos un programa que resuelva un problema concreto, ser capaces de usarlo
ASIGNATURA: SISTEMAS INFORMÁTICOS INDUSTRIALES. CURSO 4º GRUPO Octubre 2015
2. Problema de Análisis y Diseño Orientado a Objetos (10 puntos - 20 minutos) Para el código de test adjunto, se pide. 1. Diagrama de clases de diseño (2.5 puntos). 2. Implementación en C++ de la solución
TEMA 5. CONTROL DE FLUJO DEL PROGRAMA. Sentencia Instrucción Expresión Operadores + Operandos Sintaxis: Sentencia ;
TEMA 5. CONTROL DE FLUJO DEL PROGRAMA 5.1 Sentencias Una sentencia es una expresión seguida de un punto y coma. Sentencia Instrucción Expresión Operadores + Operandos Sintaxis: Sentencia ; El ; es obligatorio
Master SIA 2012/13. Programación de Sistemas Paralelos. OpenMP: Ejercicios prácticos. Facultad de Informática. Ejercicio 1.A. pi.c
Master SIA 2012/13 Facultad de Informática Programación de Sistemas Paralelos OpenMP: Ejercicios prácticos En el directorio templates/practica de tu cuenta msiaxx tienes varios programas que hay que procesar
Estructuras de Repetición: Repita Mientras.
Estructuras de Repetición: Repita Mientras. Andrés Arcia Departamento de Computación Escuela de Ingeniería de Sistemas Facultad de Ingeniería Universidad de Los Andes Programación Digital I 1 Programación
TEMA 5: PARALELISMO A NIVEL DE HILOS, TAREAS Y PETICIONES (TLP, RLP) (segunda parte)
TEMA 5: PARALELISMO A NIVEL DE HILOS, TAREAS Y PETICIONES (TLP, RLP) (segunda parte) SISTEMAS PARALELOS Y DISTRIBUIDOS www.atc.us.es Dpto. de Arquitectura y Tecnología de Computadores. Universidad de Sevilla
GUIÓN DE PRÁCTICAS 3: ESTRUCTURAS CONDICIONALES
GUIÓN DE PRÁCTICAS 3: ESTRUCTURAS CONDICIONALES Introducción. En este guión vamos a introducir aquellas estructuras en C que nos permiten seleccionar qué parte del código queremos que se ejecute. A este
Fundamentos de programación
Fundamentos de programación Estructuras de Control Estructuras de control Estructuras de control Estructura secuencial Estructura alternativa Sentencias if, if else Sentencias if else anidadas El operador
Operadores aritméticos
Bloque 3.2 Operadores aritméticos Suma : x + y Resta : x y Multiplicación : x * y División : x / y Módulo : x % y (resto de la división Si los operandos son enteros tipo del resultado
Punteros. Programación en C 1
Punteros Programación en C 1 Índice Variables y direcciones de memoria. Punteros definición, declaración e inicialización. Punteros declaración, asignación y dereferencia. Puntero nulo, tipo void. Aritmética
Ejercicios Tema 6. Funciones
Ejercicios Tema 6. Funciones 1. Programa que calcule el cuadrado de todos los números comprendidos entre dos dados. Usar una función a la que se le pasa como parámetro un valor y retorna su cuadrado. 2.
Actividad Algoritmos, Estructura y Programación I. FOR, DO-WHILE
Actividad Algoritmos, Estructura y Programación I. FOR, DO-WHILE 1. Qué es un bucle? 2. A que se denomina cuerpo de un bucle? 3. Define iteración de un bucle. 4. Cuál es el cuerpo de un bucle? 5. Qué es
8. Vectores (arrays)
8. Vectores (arrays) Fundamentos de Informática Especialidad de Electrónica 2009-2010 Ismael Etxeberria Agiriano 16/12/2009 Índice 8. Vectores (arrays) 1. Números aleatorios 2. Serie ordenada 3. Números
Los prototipos de las funciones de MPI se detallan en el document: MPI_funciones.pdf
UNIVERSIDAD POLITECNICA DE MADRIDETSII COMPUTADORES II Profesor: Dr. Claudio Rossi, PhD Profesor asistente: Julián Colorado, PhDc 11,17,18, 24 de abril de 2012 PRACTICA: USO DE MPI (MESSAGE PASSING INTERFACE)
Funciones en lenguaje C
Funciones en lenguaje C Funciones Definición: Las funciones son los bloques de construcción básicos de C. Dentro de ellas se da toda la actividad del programa. Criterios para crearlas: Se usa la estrategia
Estructura de un programa en Java. Tipos de datos básicos. class miprimerprograma{ // comentario, no es parte del programa
Contenido Estructura de un programa en Java... 2 Tipos de datos básicos... 2 Operadores... 3 Literales... 4 Entrada / Salida... 4 Sentencias condicionales... 5 Funciones... 5 Ejercicios... 6 Variables,
GUÍA DE LABORATORIO #3 ESTRUCTURAS ALGORÍTMICAS CONDICIONALES SIMPLES, DOBLES Y MÚLTIPLES
GUÍA DE LABORATORIO #3 ESTRUCTURAS ALGORÍTMICAS CONDICIONALES SIMPLES, DOBLES Y MÚLTIPLES OBJETIVO: Realizar programas en Lenguaje C aplicando las estructuras condicionales. TEMPORIZACIÓN: Inicio de la
INTRODUCCIÓN A LA PROGRAMACIÓN. 1º Bachillerato
INTRODUCCIÓN A LA PROGRAMACIÓN 1º Bachillerato Qué es un programa? Componente informático que se utiliza para realizar una determinada tarea. Se compone de algoritmos y estructuras de datos Algoritmos:
Sintaxis de los aspectos generales de un lenguaje de programación
Sintaxis de los aspectos generales de un lenguaje de programación por Iván Cruz Un lenguaje de programación cuenta con una estructura y sintaxis que debe ser utilizada exactamente como se indique para
Práctico 2: Funciones y Punteros en C La teoría general para este práctico puede consultarse en los Capítulos 4 y 5 Notas de Clase
Práctico 2: Funciones y Punteros en C La teoría general para este práctico puede consultarse en los Capítulos 4 y 5 Notas de Clase 1. Ejecute el siguiente programa y diga que hace la función calcula: #include
PROBLEMA 1. Rellena el hueco 1 (línea 23). Realiza la reserva de memoria para almacenar los n puntos.
PROBLEMA 1. El siguiente programa tiene algunos huecos en blanco que tienes que rellenar para que funcione correctamente. En cada hueco va una única línea de C, salvo en el cuerpo de la función calcula_area_triangulo,
Práctica 1: Intérprete de mandatos. Sistemas Operativos Área de Arquitectura y Tecnología de Computadores
Práctica 1: Intérprete de mandatos Introducción Desarrollo de un intérprete de mandatos (minishell) en UNIX/Linux en lenguaje C. Debe permitir: Ejecución de mandatos simples ls, cp, mv, rm, etc. Ejecución
Introducción a Sistemas Operativos: Comunicación entre Procesos
Introducción a Sistemas Operativos: Comunicación entre Procesos Clips xxx Fr ancisco J Ballesteros 1. Pipefroms Otra función de utilidad realiza el trabajo inverso, permite leer la salida de un comando
Diagrama de transiciones del autómata. Tabla de transiciones
Universidad Nacional Autónoma de México Facultad de Ingeniería Compiladores Grupo 4, Semestre 2016-1 Analizador Léxico en C Diagrama de transiciones del autómata letra letra 1 0 3 e 4 5 6 e 2 espacio Tabla
Quick Tutorial de C++ y CLion
Quick Tutorial de C++ y CLion Departamento de Computación, FCEyN, Universidad de Buenos Aires. 28 de Agosto de 2017 Bienvenidos al Laboratorio de Programación de Algoritmos y Estructura de Datos Equipo
Autor: Ing. Nahuel González INTRODUCCIÓN A C. Clase 1
INTRODUCCIÓN A C Clase 1 Introducción al lenguaje C 1967 1970 1971 1972 1989 BCPL Lenguaje B Pascal 1era versión de C ANSI C Introducción al lenguaje C Librería estandar de C: contiene módulos o funciones
Ejercicios de la sesión 4 de C resueltos
Ejercicios de la sesión 4 de C resueltos 1. Usando el procedimiento del ejercicio 2 del seminario anterior, escribe un programa que multiplique dos matrices A y B leídas de ficheros, la primera de tamaño
Sistemas Operativos: Programación de Sistemas. Curso 2006-07. Oscar Déniz Suárez Alexis Quesada Arencibia Francisco J.
Tema 2 : entorno programación linux Sistemas Operativos: Programación de Sistemas Oscar Déniz Suárez Alexis Quesada Arencibia Francisco J. Santana Pérez Curso 2006-07 Francisco J. Santana 1 Programación
Laboratorio de Paralelismo Prácticas MPI
Laboratorio de Paralelismo Prácticas MPI Tras los ejemplos MPI que hemos ido haciendo en el laboratorio, hay que realizar estos cuatro ejercicios. Los programas de partida los tienes en el directorio de
Lección 3 Sentencias de control
3.1. INTRODUCCIÓN - Hasta aquí: ejecución secuencial de los programas. - Aquí vamos a ver: Lección 3 Sentencias de control Sentencias de control Sentencias condicionales: if- y switch-case Sirven para
Estructuras de Decisión Simples y Dobles
Estructuras de Decisión Simples y Dobles Andrés Arcia Departamento de Computación Escuela de Ingeniería de Sistemas Facultad de Ingeniería Universidad de Los Andes Programación Digital I 1 Estructuras
Operadores de comparación
Operadores de comparación Los operadores de comparación en C son: Igual (==) Distinto (!=) Mayor (>) y Mayor o igual (>=) Menor (
8- LEX-Expresiones regulares
8- LEX-Expresiones regulares Objetivos: Utilizar la herramienta KEX para trabajar con expresiones regulares Recursos: Maquina virtual Linux distribución Bodhi LXterminal y FLEX Introducción Flex le permite
Capítulo 13 INSTRUCCIONES DE CONTROL REPETITIVAS. Presentación resumen del libro: "EMPEZAR DE CERO A PROGRAMAR EN lenguaje C"
Presentación resumen del libro: "EMPEZAR DE CERO A PROGRAMAR EN lenguaje C" Autor: Carlos Javier Pes Rivas ([email protected]) Capítulo 13 INSTRUCCIONES DE CONTROL REPETITIVAS 1 OBJETIVOS Conocer las
Tema 4. Control de flujo. Programación Programación - Tema 4: Control de Flujo
Tema 4 Control de flujo Programación 2015-2016 Programación - Tema 4: Control de Flujo 1 Tema 4. Control de flujo Introducción. Estructuras condicionales. Estructuras de repetición. Programación - Tema
Lenguaje de Programación: C++ Repaso de Material C++
UG Lenguaje de Programación: C++ Repaso de Material C++ Universidad de Guanajuato Octubre 2010 Variables Tipos de Variables Operadores Variable Para poder leer algo, necesitamos un lugar donde poner lo
