Annotation of ADD_ver_10/CalculosMatrices.c, revision 1.1
1.1 ! rico 1: /********************************************************************/
! 2: /* CalculosMatrices.h */
! 3: /* */
! 4: /* Copyright (c) 1997-2006 Rafael Rico (rafael.rico@uah.es) */
! 5: /* */
! 6: /* This file is part of ADD version 5.10. */
! 7: /* */
! 8: /* ADD is free software; you can redistribute it and/or modify */
! 9: /* it under the terms of the GNU General Public License as */
! 10: /* published by the Free Software Foundation; either version 2 of */
! 11: /* the License, or (at your option) any later version. */
! 12: /* */
! 13: /* ADD is distributed in the hope that it will be useful, */
! 14: /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
! 15: /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
! 16: /* GNU General Public License for more details. */
! 17: /* */
! 18: /* You should have received a copy of the GNU General Public */
! 19: /* License along with ADD; if not, write to the Free Software */
! 20: /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
! 21: /* 02111-1307 USA */
! 22: /* */
! 23: /* --------------------------- History --------------------------- */
! 24: /* */
! 25: /* Revision 1.2. 01/2006 */
! 26: /* Added GPL License and JavaDoc style documentation */
! 27: /* */
! 28: /* Revision 1.1. 09/2005 */
! 29: /* Initial Revision */
! 30: /* */
! 31: /********************************************************************/
! 32:
! 33:
! 34: /******************************************************************************/
! 35: /* MÓDULO: CalculosMatrices.c */
! 36: /* */
! 37: /* Este módulo contiene las funciones que realizan cálculos sobre */
! 38: /* las matrices. */
! 39: /******************************************************************************/
! 40: /* Fecha: 26 de septiembre de 2005 */
! 41: /******************************************************************************/
! 42:
! 43: #include <stdio.h>
! 44: #include <stdlib.h>
! 45: #include <string.h>
! 46:
! 47: #include "defines.h"
! 48: #include "tipos.h"
! 49: #include "calculosmatrices.h"
! 50:
! 51: /* configuración */
! 52: extern struct argumentos configuracion;
! 53:
! 54: /* análisis de dependencias de datos */
! 55: extern struct punterosD matriz;
! 56: extern unsigned char **matrizC;
! 57: extern char **OrdenParcial;
! 58:
! 59: /* parámetros asociados a las matrices */
! 60: extern parametromatriz *pasos;
! 61: extern parametromatriz *mediapasos;
! 62: extern parametromatriz *grado;
! 63: extern parametromatriz *mediagrado;
! 64: extern parametromatriz *acoplo;
! 65: extern parametromatriz *mediaacoplo;
! 66:
! 67: /* otros resultados */
! 68: extern unsigned long *distribucionpasos;
! 69:
! 70:
! 71: /* esta función calcula la matriz de caminos de dependencias C */
! 72: /* a partir de una matriz de dependencias D */
! 73: /* devuelve el número de pasos de computación requeridos para */
! 74: /* finalizar la computación de la secuencia expresada por D */
! 75: /* (la matriz de caminos devuelta no ha sido reducida a 0s y 1s) */
! 76:
! 77: /* esta función es muy consumidora de tiempo ya que calcula potencias de D */
! 78:
! 79: unsigned int CalcularMatrizCaminos(unsigned char **D, unsigned char **C)
! 80: {
! 81: char mensaje[MAX_LINE];
! 82: unsigned char *v; /* vector temporal */
! 83: unsigned char **tmp; /* matriz temporal */
! 84:
! 85: unsigned int i, j, k, potencia;
! 86: unsigned int suma;
! 87: unsigned char matriz_nula;
! 88:
! 89:
! 90: if(D == NULL)
! 91: {
! 92: sprintf(mensaje, "[CalcularMatrizCaminos] La matriz D indicada no existe");
! 93: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 94: }
! 95:
! 96: /* necesito un vector y una matriz temporal de 'unsigned char' */
! 97: /* para calcular las sucesivas potencias de la matriz D */
! 98:
! 99: /* hago la reserva de memoria para el vector */
! 100: v = calloc(configuracion.ventana , sizeof(unsigned char *));
! 101: if (v == NULL)
! 102: {
! 103: sprintf(mensaje, "[CalcularMatrizCaminos] Memoria insuficiente");
! 104: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 105: /* el programa finaliza si no hay memoria suficiente */
! 106: }
! 107:
! 108: /* hago la reserva de memoria para la matriz */
! 109: /* 1º un puntero por cada fila */
! 110: tmp = calloc(configuracion.ventana , sizeof(unsigned char *));
! 111: if (tmp == NULL)
! 112: {
! 113: sprintf(mensaje, "[CalcularMatrizCaminos] Memoria insuficiente");
! 114: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 115: /* el programa finaliza si no hay memoria suficiente */
! 116: }
! 117: /* 2º un 'char' por cada columna */
! 118: for(i=0; i<configuracion.ventana; i++)
! 119: {
! 120: tmp[i] = calloc(configuracion.ventana, sizeof(unsigned char));
! 121: if (tmp[i] == NULL)
! 122: {
! 123: sprintf(mensaje, "[CalcularMatrizCaminos] Memoria insuficiente");
! 124: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 125: /* el programa finaliza si no hay memoria suficiente */
! 126: }
! 127: }
! 128:
! 129:
! 130: /* inicio la matriz temporal con la matriz 'identidad' (1s en la diagonal) */
! 131: /* al reservar con 'calloc' se rellena con 0s */
! 132:
! 133: for(i=0; i<configuracion.ventana; i++) tmp[i][i] = 1;
! 134:
! 135:
! 136: /* calculo sucesivas potencias de la matriz 'D' hasta que se anule */
! 137: /* utilizo la expresión TMP * D = TMP */
! 138: /* el uso del vector me permite escribir el resultado sobre 'TMP' */
! 139: for(potencia=0; potencia<configuracion.ventana; potencia++)
! 140: {
! 141: for(i=0; i<configuracion.ventana; i++)
! 142: {
! 143: for(k=0; k<configuracion.ventana; k++) v[k]=tmp[i][k];
! 144: for(j=0; j<configuracion.ventana; j++)
! 145: {
! 146: suma = 0;
! 147: for(k=0; k<configuracion.ventana; k++)
! 148: {
! 149: suma += v[k] * D[k][j];
! 150: }
! 151: tmp[i][j] = suma;
! 152: }
! 153: }
! 154:
! 155: /* la matriz 'TMP' contiene la n-ésima+1 potencia de 'D' */
! 156:
! 157: /* ahora evalúo si el resultado es la matriz nula */
! 158: /* si es así no tengo que continuar ya que no hay */
! 159: /* caminos de dependencias de longitud mayor */
! 160:
! 161: matriz_nula = SI;
! 162: for(i=0; i<configuracion.ventana; i++)
! 163: {
! 164: for(j=0; j<configuracion.ventana; j++)
! 165: {
! 166: if(tmp[i][j] != 0) {matriz_nula = NO; break;}
! 167: }
! 168: if(matriz_nula == NO) break;
! 169: }
! 170: if(matriz_nula == SI) break;
! 171:
! 172: /* sumo la nueva potencia de la matriz de dependencias D^^p */
! 173: /* a la matriz de caminos parcial 'C' si me han pasado un puntero no nulo */
! 174: if(*C != NULL)
! 175: {
! 176: for(i=0; i<configuracion.ventana; i++)
! 177: {
! 178: for(j=0; j<configuracion.ventana; j++) C[i][j] += tmp[i][j];
! 179: }
! 180: }
! 181: }
! 182:
! 183: /* libero la memoria reservada anteriormente */
! 184: /* libero el vector */
! 185: free(v);
! 186: /* libero la matriz */
! 187: for(i=0; i<configuracion.ventana; i++) free(tmp[i]); free(tmp);
! 188:
! 189: return potencia+1; /* devuelve el rango de la primera potencia nula de 'D' */
! 190: }
! 191:
! 192:
! 193: /* esta función establece la lista del orden parcial contenido en D */
! 194: /* y devuelve el número de pasos de computación del camino crítico */
! 195: /* si le pasamos un puntero NULO en el parámetro lista sólo realiza el */
! 196: /* calculo de pasos de computación (método más rápido que el anterior) */
! 197: /* se asume que la matriz D no ha sido reducida a 0s y 1s */
! 198:
! 199: unsigned int ListaOrdenParcial(unsigned char **D, char **lista)
! 200: {
! 201: char mensaje[MAX_LINE];
! 202: unsigned char *lanzadas; /* vector de instrucciones lanzadas */
! 203: unsigned char **tmp; /* matriz temporal */
! 204:
! 205: unsigned int pasos, procesadas;
! 206: unsigned int i, j;
! 207: char cadena[6]; /* cadena para pasar enteros a strings */
! 208:
! 209:
! 210: if(D == NULL)
! 211: {
! 212: sprintf(mensaje, "[ListaOrdenParcial] La matriz D indicada no existe");
! 213: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 214: }
! 215:
! 216: /* necesito un vector y una matriz temporal de 'unsigned char' */
! 217: /* para calcular las sucesivas potencias de la matriz D */
! 218:
! 219: /* hago la reserva de memoria para el vector */
! 220: lanzadas = calloc(configuracion.ventana , sizeof(unsigned char *));
! 221: if (lanzadas == NULL)
! 222: {
! 223: sprintf(mensaje, "[ListaOrdenParcial] Memoria insuficiente");
! 224: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 225: /* el programa finaliza si no hay memoria suficiente */
! 226: }
! 227:
! 228: /* hago la reserva de memoria para la matriz */
! 229: /* 1º un puntero por cada fila */
! 230: tmp = calloc(configuracion.ventana , sizeof(unsigned char *));
! 231: if (tmp == NULL)
! 232: {
! 233: sprintf(mensaje, "[ListaOrdenParcial] Memoria insuficiente");
! 234: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 235: /* el programa finaliza si no hay memoria suficiente */
! 236: }
! 237: /* 2º un 'char' por cada columna */
! 238: for(i=0; i<configuracion.ventana; i++)
! 239: {
! 240: tmp[i] = calloc(configuracion.ventana, sizeof(unsigned char));
! 241: if (tmp[i] == NULL)
! 242: {
! 243: sprintf(mensaje, "[ListaOrdenParcial] Memoria insuficiente");
! 244: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 245: /* el programa finaliza si no hay memoria suficiente */
! 246: }
! 247: }
! 248:
! 249: /* copio la matriz de dependencias D sobre la temporal */
! 250: for(i=0; i<configuracion.ventana; i++)
! 251: {
! 252: for(j=0; j<configuracion.ventana; j++) tmp[i][j] = D[i][j];
! 253: }
! 254:
! 255: /* pongo a cero el vector de lanzadas */
! 256: for(i=0; i<configuracion.ventana; i++) lanzadas[i] = 0;
! 257:
! 258: /* inicio el contador de pasos de computaci¢n */
! 259: pasos = 0;
! 260:
! 261: /* inicio el contador de instrucciones procesadas */
! 262: procesadas = 0;
! 263:
! 264:
! 265: while(configuracion.ventana - procesadas)
! 266: {
! 267: pasos++;
! 268:
! 269: /* busco tareas independientes entre las NO lanzadas */
! 270: for(i=0; i<configuracion.ventana; i++)
! 271: {
! 272: if(lanzadas[i]==0) /* si es 0 significa que no se ha lanzado */
! 273: {
! 274: /* miro si el vector de dependencias es nulo */
! 275: for(j=0; j<i; j++)
! 276: {
! 277: if(tmp[i][j]!=0) break;
! 278: }
! 279: if(j==i)
! 280: {
! 281: lanzadas[i]=1; /* la instrucci¢n es independiente */
! 282:
! 283: /* anoto la instrucción en la lista del orden parcial */
! 284: /* en el paso de computación en curso */
! 285: if(lista != NULL)
! 286: {
! 287: sprintf(cadena, "%u", i);
! 288: AgregarElementoLista(lista[pasos-1], cadena);
! 289: }
! 290: }
! 291: }
! 292: }
! 293:
! 294: /* ahora actualizo la matriz de dependencias con la lista de */
! 295: /* instrucciones independientes que han sido lanzadas */
! 296:
! 297: for(i=0; i<configuracion.ventana; i++)
! 298: {
! 299: if(lanzadas[i]==1) /* si es 1 significa que es independiente */
! 300: {
! 301: for(j=i+1; j<configuracion.ventana; j++)
! 302: {
! 303: if(tmp[j][i]!=0) tmp[j][i]=0;
! 304: }
! 305: }
! 306: }
! 307:
! 308: /* ahora actualizo el vector de lanzadas */
! 309: for(i=0; i<configuracion.ventana; i++)
! 310: {
! 311: if(lanzadas[i]==1)
! 312: {
! 313: lanzadas[i]=2; /* significa que ha sido procesada */
! 314: procesadas++;
! 315: }
! 316: }
! 317: }
! 318:
! 319: /* libero la memoria reservada anteriormente */
! 320: /* libero el vector */
! 321: free(lanzadas);
! 322: /* libero la matriz */
! 323: for(i=0; i<configuracion.ventana; i++) free(tmp[i]); free(tmp);
! 324:
! 325: return pasos;
! 326: }
! 327:
! 328:
! 329: /* esta función determina el 'acoplamiento' de una matriz de dependencias de datos */
! 330:
! 331: unsigned int Acoplamiento(unsigned char **D)
! 332: {
! 333: char mensaje[MAX_LINE];
! 334: unsigned int i, j;
! 335: unsigned int acoplo = 0;
! 336:
! 337: if(D == NULL)
! 338: {
! 339: sprintf(mensaje, "[Acoplamiento] La matriz D indicada no existe");
! 340: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 341: }
! 342:
! 343: /* puesto que las matrices se obtienen de la secuencia de código */
! 344: /* estamos seguros de que son canónicas y, por tanto, no es necesario */
! 345: /* hacer el recorrido completo de todas sus componentes */
! 346: /* basta con empezar en la instrucción 1 y recorres columnas hasta la diagonal */
! 347: for(i=1; i<configuracion.ventana; i++)
! 348: {
! 349: for(j=0; j<i; j++) if(D[i][j] != 0) acoplo++;
! 350: }
! 351:
! 352: return acoplo;
! 353: }
! 354:
! 355:
! 356:
! 357: /* esta función reserva memoria para un array de 'num_cadenas' de punteros /*
! 358: /* a cadenas de caracteres de tamaño fijo 'tamano' y devuelve el puntero */
! 359:
! 360: /* con esta estructura implantaremos la lista de orden parcial */
! 361: /* trabajando con punteros a char y cadenas de tamaño variable puede */
! 362: /* ser más eficaz pero es necesario ser más cuidadoso */
! 363:
! 364: char ** CrearArrayStrings(unsigned int num_cadenas, unsigned int tamano)
! 365: {
! 366: char mensaje[MAX_LINE];
! 367: unsigned int i;
! 368: char **listado;
! 369:
! 370: /* 1º un puntero por cada fila */
! 371: listado = calloc(num_cadenas, sizeof(char *));
! 372: if (listado == NULL)
! 373: {
! 374: sprintf(mensaje, "[CrearArrayStrings] Memoria insuficiente");
! 375: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 376: /* el programa finaliza si no hay memoria suficiente */
! 377: }
! 378: /* 2º cuatro 'char' por cada columna (3 caracteres de número y un separador ':') */
! 379: for(i=0; i<configuracion.ventana; i++)
! 380: {
! 381: listado[i] = calloc(tamano, sizeof(char));
! 382: if (listado[i] == NULL)
! 383: {
! 384: sprintf(mensaje, "[CrearArrayStrings] Memoria insuficiente");
! 385: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 386: /* el programa finaliza si no hay memoria suficiente */
! 387: }
! 388: }
! 389: return listado;
! 390: }
! 391:
! 392:
! 393: /* reserva memoria para construir un listado de orden parcial: */
! 394: /* cada línea del listado corresponde a un paso de computación */
! 395: /* y cada paso de computación contiene una cadena con la lista */
! 396: /* de instrucciones sin dependencias de datos en ese momento */
! 397:
! 398: void CrearListaOrdenParcial()
! 399: {
! 400: unsigned int dim;
! 401:
! 402: dim = configuracion.ventana;
! 403:
! 404: OrdenParcial = CrearArrayStrings(dim, 4*dim);
! 405: }
! 406:
! 407:
! 408: /* inicia el listado de orden parcial rellenando con la cadena vacía '\0' */
! 409:
! 410: void IniciarListaOrdenParcial()
! 411: {
! 412: unsigned int i, dim;
! 413:
! 414: dim = configuracion.ventana;
! 415:
! 416: if(OrdenParcial != NULL) for(i=0; i<dim; i++) *OrdenParcial[i] = '\0';
! 417: }
! 418:
! 419:
! 420: /* libera la memoria reservada para el listado de orden parcial */
! 421:
! 422: void LiberarMemoriaListaOrdenParcial()
! 423: {
! 424: unsigned int i,dim;
! 425:
! 426: dim = configuracion.ventana;
! 427:
! 428: if(OrdenParcial != NULL)
! 429: {
! 430: for(i=0; i<dim; i++)
! 431: {
! 432: free(OrdenParcial[i]);
! 433: }
! 434: free(OrdenParcial);
! 435: }
! 436: }
! 437:
! 438:
! 439: /* crea la matriz de caminos de dependencias */
! 440:
! 441: void CrearMatrizCaminos()
! 442: {
! 443: matrizC = CrearMatriz();
! 444: }
! 445:
! 446:
! 447: /* inicia la matriz de caminos de dependencias */
! 448:
! 449: void IniciarMatrizCaminos()
! 450: {
! 451: IniciarMatriz(matrizC);
! 452: }
! 453:
! 454:
! 455: /* libera la memoria de la matriz de caminos */
! 456:
! 457: void LiberarMemoriaMatrizCaminos()
! 458: {
! 459: LiberarMemoriaMatriz(matrizC);
! 460: }
! 461:
! 462:
! 463: /* reserva espacio en memoria para una variable agregada */
! 464:
! 465: parametromatriz * CrearVariableAgregada()
! 466: {
! 467: char mensaje[MAX_LINE];
! 468: parametromatriz *variable;
! 469:
! 470: variable = calloc(1, sizeof(parametromatriz));
! 471: if (variable == NULL)
! 472: {
! 473: sprintf(mensaje, "[CrearVariableAgragada] Memoria insuficiente");
! 474: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 475: /* el programa finaliza si no hay memoria suficiente */
! 476: }
! 477:
! 478: return variable;
! 479: }
! 480:
! 481:
! 482: /* inicia a 0 una variable agregada */
! 483:
! 484: void IniciarVariableAgregada(parametromatriz *variable)
! 485: {
! 486: variable->Ddatoexp = 0.0;
! 487: variable->Ddir_exp = 0.0;
! 488: variable->Dpilaexp = 0.0;
! 489: variable->Destadoexp = 0.0;
! 490:
! 491: variable->Ddatoimp = 0.0;
! 492: variable->Ddir_imp = 0.0;
! 493: variable->Dpilaimp = 0.0;
! 494: variable->Destadoimp = 0.0;
! 495:
! 496: variable->ADdatoexp = 0.0;
! 497: variable->ADdir_exp = 0.0;
! 498: variable->ADpilaexp = 0.0;
! 499: variable->ADestadoexp = 0.0;
! 500:
! 501: variable->ADdatoimp = 0.0;
! 502: variable->ADdir_imp = 0.0;
! 503: variable->ADpilaimp = 0.0;
! 504: variable->ADestadoimp = 0.0;
! 505:
! 506: variable->Sdatoexp = 0.0;
! 507: variable->Sdir_exp = 0.0;
! 508: variable->Spilaexp = 0.0;
! 509: variable->Sestadoexp = 0.0;
! 510:
! 511: variable->Sdatoimp = 0.0;
! 512: variable->Sdir_imp = 0.0;
! 513: variable->Spilaimp = 0.0;
! 514: variable->Sestadoimp = 0.0;
! 515:
! 516: variable->D = 0.0;
! 517: }
! 518:
! 519:
! 520:
! 521: /* esta función calcula el nuevo promedio de una variable agregada (media) a partir del */
! 522: /* índice (n) y del valor actual o en curso de esa variable (actual) */
! 523:
! 524: /*
! 525: void CalcularPromedioVariableAgregada(parametromatriz *media, parametromatriz *actual, unsigned long n)
! 526: {
! 527: if(matriz.Ddatoexp != NULL) media->Ddatoexp = ((n - 1) * media->Ddatoexp + actual->Ddatoexp) / n;
! 528: if(matriz.Ddir_exp != NULL) media->Ddir_exp = ((n - 1) * media->Ddir_exp + actual->Ddir_exp) / n;
! 529: if(matriz.Dpilaexp != NULL) media->Dpilaexp = ((n - 1) * media->Dpilaexp + actual->Dpilaexp) / n;
! 530: if(matriz.Destadoexp != NULL) media->Destadoexp = ((n - 1) * media->Destadoexp + actual->Destadoexp) / n;
! 531:
! 532: if(matriz.Ddatoimp != NULL) media->Ddatoimp = ((n - 1) * media->Ddatoimp + actual->Ddatoimp) / n;
! 533: if(matriz.Ddir_imp != NULL) media->Ddir_imp = ((n - 1) * media->Ddir_imp + actual->Ddir_imp) / n;
! 534: if(matriz.Dpilaimp != NULL) media->Dpilaimp = ((n - 1) * media->Dpilaimp + actual->Dpilaimp) / n;
! 535: if(matriz.Destadoimp != NULL) media->Destadoimp = ((n - 1) * media->Destadoimp + actual->Destadoimp) / n;
! 536:
! 537: if(matriz.ADdatoexp != NULL) media->ADdatoexp = ((n - 1) * media->ADdatoexp + actual->ADdatoexp) / n;
! 538: if(matriz.ADdir_exp != NULL) media->ADdir_exp = ((n - 1) * media->ADdir_exp + actual->ADdir_exp) / n;
! 539: if(matriz.ADpilaexp != NULL) media->ADpilaexp = ((n - 1) * media->ADpilaexp + actual->ADpilaexp) / n;
! 540: if(matriz.ADestadoexp != NULL) media->ADestadoexp = ((n - 1) * media->ADestadoexp + actual->ADestadoexp) / n;
! 541:
! 542: if(matriz.ADdatoimp != NULL) media->ADdatoimp = ((n - 1) * media->ADdatoimp + actual->ADdatoimp) / n;
! 543: if(matriz.ADdir_imp != NULL) media->ADdir_imp = ((n - 1) * media->ADdir_imp + actual->ADdir_imp) / n;
! 544: if(matriz.ADpilaimp != NULL) media->ADpilaimp = ((n - 1) * media->ADpilaimp + actual->ADpilaimp) / n;
! 545: if(matriz.ADestadoimp != NULL) media->ADestadoimp = ((n - 1) * media->ADestadoimp + actual->ADestadoimp) / n;
! 546:
! 547: if(matriz.Sdatoexp != NULL) media->Sdatoexp = ((n - 1) * media->Sdatoexp + actual->Sdatoexp) / n;
! 548: if(matriz.Sdir_exp != NULL) media->Sdir_exp = ((n - 1) * media->Sdir_exp + actual->Sdir_exp) / n;
! 549: if(matriz.Spilaexp != NULL) media->Spilaexp = ((n - 1) * media->Spilaexp + actual->Spilaexp) / n;
! 550: if(matriz.Sestadoexp != NULL) media->Sestadoexp = ((n - 1) * media->Sestadoexp + actual->Sestadoexp) / n;
! 551:
! 552: if(matriz.Sdatoimp != NULL) media->Sdatoimp = ((n - 1) * media->Sdatoimp + actual->Sdatoimp) / n;
! 553: if(matriz.Sdir_imp != NULL) media->Sdir_imp = ((n - 1) * media->Sdir_imp + actual->Sdir_imp) / n;
! 554: if(matriz.Spilaimp != NULL) media->Spilaimp = ((n - 1) * media->Spilaimp + actual->Spilaimp) / n;
! 555: if(matriz.Sestadoimp != NULL) media->Sestadoimp = ((n - 1) * media->Sestadoimp + actual->Sestadoimp) / n;
! 556:
! 557: if(matriz.D != NULL) media->D = ((n - 1) * media->D + actual->D) / n;
! 558: }
! 559: */
! 560:
! 561:
! 562: /* utilizando la función: */
! 563: /* double CalcularNuevoPromedio (double promedioanterior, double valoractual, unsigned long n)
! 564: /* es más compacto aunque quizá algo más lento */
! 565:
! 566: void CalcularPromedioVariableAgregada(parametromatriz *media, parametromatriz *actual, unsigned long n)
! 567: {
! 568: if(matriz.Ddatoexp != NULL) media->Ddatoexp = CalcularNuevoPromedio(media->Ddatoexp, actual->Ddatoexp, n);
! 569: if(matriz.Ddir_exp != NULL) media->Ddir_exp = CalcularNuevoPromedio(media->Ddir_exp, actual->Ddir_exp, n);
! 570: if(matriz.Dpilaexp != NULL) media->Dpilaexp = CalcularNuevoPromedio(media->Dpilaexp, actual->Dpilaexp, n);
! 571: if(matriz.Destadoexp != NULL) media->Destadoexp = CalcularNuevoPromedio(media->Destadoexp, actual->Destadoexp, n);
! 572:
! 573: if(matriz.Ddatoimp != NULL) media->Ddatoimp = CalcularNuevoPromedio(media->Ddatoimp, actual->Ddatoimp, n);
! 574: if(matriz.Ddir_imp != NULL) media->Ddir_imp = CalcularNuevoPromedio(media->Ddir_imp, actual->Ddir_imp, n);
! 575: if(matriz.Dpilaimp != NULL) media->Dpilaimp = CalcularNuevoPromedio(media->Dpilaimp, actual->Dpilaimp, n);
! 576: if(matriz.Destadoimp != NULL) media->Destadoimp = CalcularNuevoPromedio(media->Destadoimp, actual->Destadoimp, n);
! 577:
! 578: if(matriz.ADdatoexp != NULL) media->ADdatoexp = CalcularNuevoPromedio(media->ADdatoexp, actual->ADdatoexp, n);
! 579: if(matriz.ADdir_exp != NULL) media->ADdir_exp = CalcularNuevoPromedio(media->ADdir_exp, actual->ADdir_exp, n);
! 580: if(matriz.ADpilaexp != NULL) media->ADpilaexp = CalcularNuevoPromedio(media->ADpilaexp, actual->ADpilaexp, n);
! 581: if(matriz.ADestadoexp != NULL) media->ADestadoexp = CalcularNuevoPromedio(media->ADestadoexp, actual->ADestadoexp, n);
! 582:
! 583: if(matriz.ADdatoimp != NULL) media->ADdatoimp = CalcularNuevoPromedio(media->ADdatoimp, actual->ADdatoimp, n);
! 584: if(matriz.ADdir_imp != NULL) media->ADdir_imp = CalcularNuevoPromedio(media->ADdir_imp, actual->ADdir_imp, n);
! 585: if(matriz.ADpilaimp != NULL) media->ADpilaimp = CalcularNuevoPromedio(media->ADpilaimp, actual->ADpilaimp, n);
! 586: if(matriz.ADestadoimp != NULL) media->ADestadoimp = CalcularNuevoPromedio(media->ADestadoimp, actual->ADestadoimp, n);
! 587:
! 588: if(matriz.Sdatoexp != NULL) media->Sdatoexp = CalcularNuevoPromedio(media->Sdatoexp, actual->Sdatoexp, n);
! 589: if(matriz.Sdir_exp != NULL) media->Sdir_exp = CalcularNuevoPromedio(media->Sdir_exp, actual->Sdir_exp, n);
! 590: if(matriz.Spilaexp != NULL) media->Spilaexp = CalcularNuevoPromedio(media->Spilaexp, actual->Spilaexp, n);
! 591: if(matriz.Sestadoexp != NULL) media->Sestadoexp = CalcularNuevoPromedio(media->Sestadoexp, actual->Sestadoexp, n);
! 592:
! 593: if(matriz.Sdatoimp != NULL) media->Sdatoimp = CalcularNuevoPromedio(media->Sdatoimp, actual->Sdatoimp, n);
! 594: if(matriz.Sdir_imp != NULL) media->Sdir_imp = CalcularNuevoPromedio(media->Sdir_imp, actual->Sdir_imp, n);
! 595: if(matriz.Spilaimp != NULL) media->Spilaimp = CalcularNuevoPromedio(media->Spilaimp, actual->Spilaimp, n);
! 596: if(matriz.Sestadoimp != NULL) media->Sestadoimp = CalcularNuevoPromedio(media->Sestadoimp, actual->Sestadoimp, n);
! 597:
! 598: if(matriz.D != NULL) media->D = CalcularNuevoPromedio(media->D, actual->D, n);
! 599: }
! 600:
! 601:
! 602: /* esta función calcula los pasos de computación de cada matriz de dependencias */
! 603:
! 604: /* para calcular los pasos de computación se usa el método más rápido, es decir, */
! 605: /* construir la lista de orden parcial... aunque no se anote ya que pasamos un puntero nulo */
! 606:
! 607: void CalcularPasosComputacion(parametromatriz *pasos)
! 608: {
! 609: if(matriz.Ddatoexp != NULL) pasos->Ddatoexp = ListaOrdenParcial(matriz.Ddatoexp, NULL);
! 610: if(matriz.Ddir_exp != NULL) pasos->Ddir_exp = ListaOrdenParcial(matriz.Ddir_exp, NULL);
! 611: if(matriz.Dpilaexp != NULL) pasos->Dpilaexp = ListaOrdenParcial(matriz.Dpilaexp, NULL);
! 612: if(matriz.Destadoexp != NULL) pasos->Destadoexp = ListaOrdenParcial(matriz.Destadoexp, NULL);
! 613:
! 614: if(matriz.Ddatoimp != NULL) pasos->Ddatoimp = ListaOrdenParcial(matriz.Ddatoimp, NULL);
! 615: if(matriz.Ddir_imp != NULL) pasos->Ddir_imp = ListaOrdenParcial(matriz.Ddir_imp, NULL);
! 616: if(matriz.Dpilaimp != NULL) pasos->Dpilaimp = ListaOrdenParcial(matriz.Dpilaimp, NULL);
! 617: if(matriz.Destadoimp != NULL) pasos->Destadoimp = ListaOrdenParcial(matriz.Destadoimp, NULL);
! 618:
! 619: if(matriz.ADdatoexp != NULL) pasos->ADdatoexp = ListaOrdenParcial(matriz.ADdatoexp, NULL);
! 620: if(matriz.ADdir_exp != NULL) pasos->ADdir_exp = ListaOrdenParcial(matriz.ADdir_exp, NULL);
! 621: if(matriz.ADpilaexp != NULL) pasos->ADpilaexp = ListaOrdenParcial(matriz.ADpilaexp, NULL);
! 622: if(matriz.ADestadoexp != NULL) pasos->ADestadoexp = ListaOrdenParcial(matriz.ADestadoexp, NULL);
! 623:
! 624: if(matriz.ADdatoimp != NULL) pasos->ADdatoimp = ListaOrdenParcial(matriz.ADdatoimp, NULL);
! 625: if(matriz.ADdir_imp != NULL) pasos->ADdir_imp = ListaOrdenParcial(matriz.ADdir_imp, NULL);
! 626: if(matriz.ADpilaimp != NULL) pasos->ADpilaimp = ListaOrdenParcial(matriz.ADpilaimp, NULL);
! 627: if(matriz.ADestadoimp != NULL) pasos->ADestadoimp = ListaOrdenParcial(matriz.ADestadoimp, NULL);
! 628:
! 629: if(matriz.Sdatoexp != NULL) pasos->Sdatoexp = ListaOrdenParcial(matriz.Sdatoexp, NULL);
! 630: if(matriz.Sdir_exp != NULL) pasos->Sdir_exp = ListaOrdenParcial(matriz.Sdir_exp, NULL);
! 631: if(matriz.Spilaexp != NULL) pasos->Spilaexp = ListaOrdenParcial(matriz.Spilaexp, NULL);
! 632: if(matriz.Sestadoexp != NULL) pasos->Sestadoexp = ListaOrdenParcial(matriz.Sestadoexp, NULL);
! 633:
! 634: if(matriz.Sdatoimp != NULL) pasos->Sdatoimp = ListaOrdenParcial(matriz.Sdatoimp, NULL);
! 635: if(matriz.Sdir_imp != NULL) pasos->Sdir_imp = ListaOrdenParcial(matriz.Sdir_imp, NULL);
! 636: if(matriz.Spilaimp != NULL) pasos->Spilaimp = ListaOrdenParcial(matriz.Spilaimp, NULL);
! 637: if(matriz.Sestadoimp != NULL) pasos->Sestadoimp = ListaOrdenParcial(matriz.Sestadoimp, NULL);
! 638:
! 639: if(matriz.D != NULL) pasos->D = ListaOrdenParcial(matriz.D, NULL);
! 640: }
! 641:
! 642:
! 643:
! 644: /* esta función calcula el grado de paralelismo a partir de los pasos de computación */
! 645: /* ver si es necesario prevenir la división por 0 */
! 646:
! 647: /*
! 648: void CalcularGradoParalelismo(parametromatriz *pasos, parametromatriz *grado)
! 649: {
! 650: if(matriz.Ddatoexp != NULL) grado->Ddatoexp = 1 / pasos->Ddatoexp;
! 651: if(matriz.Ddir_exp != NULL) grado->Ddir_exp = 1 / pasos->Ddir_exp;
! 652: if(matriz.Dpilaexp != NULL) grado->Dpilaexp = 1 / pasos->Dpilaexp;
! 653: if(matriz.Destadoexp != NULL) grado->Destadoexp = 1 / pasos->Destadoexp;
! 654:
! 655: if(matriz.Ddatoimp != NULL) grado->Ddatoimp = 1 / pasos->Ddatoimp;
! 656: if(matriz.Ddir_imp != NULL) grado->Ddir_imp = 1 / pasos->Ddir_imp;
! 657: if(matriz.Dpilaimp != NULL) grado->Dpilaimp = 1 / pasos->Dpilaimp;
! 658: if(matriz.Destadoimp != NULL) grado->Destadoimp = 1 / pasos->Destadoimp;
! 659:
! 660: if(matriz.ADdatoexp != NULL) grado->ADdatoexp = 1 / pasos->ADdatoexp;
! 661: if(matriz.ADdir_exp != NULL) grado->ADdir_exp = 1 / pasos->ADdir_exp;
! 662: if(matriz.ADpilaexp != NULL) grado->ADpilaexp = 1 / pasos->ADpilaexp;
! 663: if(matriz.ADestadoexp != NULL) grado->ADestadoexp = 1 / pasos->ADestadoexp;
! 664:
! 665: if(matriz.ADdatoimp != NULL) grado->ADdatoimp = 1 / pasos->ADdatoimp;
! 666: if(matriz.ADdir_imp != NULL) grado->ADdir_imp = 1 / pasos->ADdir_imp;
! 667: if(matriz.ADpilaimp != NULL) grado->ADpilaimp = 1 / pasos->ADpilaimp;
! 668: if(matriz.ADestadoimp != NULL) grado->ADestadoimp = 1 / pasos->ADestadoimp;
! 669:
! 670: if(matriz.Sdatoexp != NULL) grado->Sdatoexp = 1 / pasos->Sdatoexp;
! 671: if(matriz.Sdir_exp != NULL) grado->Sdir_exp = 1 / pasos->Sdir_exp;
! 672: if(matriz.Spilaexp != NULL) grado->Spilaexp = 1 / pasos->Spilaexp;
! 673: if(matriz.Sestadoexp != NULL) grado->Sestadoexp = 1 / pasos->Sestadoexp;
! 674:
! 675: if(matriz.Sdatoimp != NULL) grado->Sdatoimp = 1 / pasos->Sdatoimp;
! 676: if(matriz.Sdir_imp != NULL) grado->Sdir_imp = 1 / pasos->Sdir_imp;
! 677: if(matriz.Spilaimp != NULL) grado->Spilaimp = 1 / pasos->Spilaimp;
! 678: if(matriz.Sestadoimp != NULL) grado->Sestadoimp = 1 / pasos->Sestadoimp;
! 679:
! 680: if(matriz.D != NULL) grado->D = 1 / pasos->D;
! 681: }
! 682:
! 683: */
! 684:
! 685:
! 686:
! 687: /* esta función calcula el grado de paralelismo NORMALIZADO a partir de */
! 688: /* la dimensión de la ventana de instrucciones y de los pasos de computación */
! 689:
! 690: void CalcularGradoParalelismoNormalizado(parametromatriz *pasos, parametromatriz *grado)
! 691: {
! 692: unsigned int dim;
! 693:
! 694: dim = configuracion.ventana;
! 695:
! 696: if(matriz.Ddatoexp != NULL) grado->Ddatoexp = InversoNormalizado(dim, pasos->Ddatoexp);
! 697: if(matriz.Ddir_exp != NULL) grado->Ddir_exp = InversoNormalizado(dim, pasos->Ddir_exp);
! 698: if(matriz.Dpilaexp != NULL) grado->Dpilaexp = InversoNormalizado(dim, pasos->Dpilaexp);
! 699: if(matriz.Destadoexp != NULL) grado->Destadoexp = InversoNormalizado(dim, pasos->Destadoexp);
! 700:
! 701: if(matriz.Ddatoimp != NULL) grado->Ddatoimp = InversoNormalizado(dim, pasos->Ddatoimp);
! 702: if(matriz.Ddir_imp != NULL) grado->Ddir_imp = InversoNormalizado(dim, pasos->Ddir_imp);
! 703: if(matriz.Dpilaimp != NULL) grado->Dpilaimp = InversoNormalizado(dim, pasos->Dpilaimp);
! 704: if(matriz.Destadoimp != NULL) grado->Destadoimp = InversoNormalizado(dim, pasos->Destadoimp);
! 705:
! 706: if(matriz.ADdatoexp != NULL) grado->ADdatoexp = InversoNormalizado(dim, pasos->ADdatoexp);
! 707: if(matriz.ADdir_exp != NULL) grado->ADdir_exp = InversoNormalizado(dim, pasos->ADdir_exp);
! 708: if(matriz.ADpilaexp != NULL) grado->ADpilaexp = InversoNormalizado(dim, pasos->ADpilaexp);
! 709: if(matriz.ADestadoexp != NULL) grado->ADestadoexp = InversoNormalizado(dim, pasos->ADestadoexp);
! 710:
! 711: if(matriz.ADdatoimp != NULL) grado->ADdatoimp = InversoNormalizado(dim, pasos->ADdatoimp);
! 712: if(matriz.ADdir_imp != NULL) grado->ADdir_imp = InversoNormalizado(dim, pasos->ADdir_imp);
! 713: if(matriz.ADpilaimp != NULL) grado->ADpilaimp = InversoNormalizado(dim, pasos->ADpilaimp);
! 714: if(matriz.ADestadoimp != NULL) grado->ADestadoimp = InversoNormalizado(dim, pasos->ADestadoimp);
! 715:
! 716: if(matriz.Sdatoexp != NULL) grado->Sdatoexp = InversoNormalizado(dim, pasos->Sdatoexp);
! 717: if(matriz.Sdir_exp != NULL) grado->Sdir_exp = InversoNormalizado(dim, pasos->Sdir_exp);
! 718: if(matriz.Spilaexp != NULL) grado->Spilaexp = InversoNormalizado(dim, pasos->Spilaexp);
! 719: if(matriz.Sestadoexp != NULL) grado->Sestadoexp = InversoNormalizado(dim, pasos->Sestadoexp);
! 720:
! 721: if(matriz.Sdatoimp != NULL) grado->Sdatoimp = InversoNormalizado(dim, pasos->Sdatoimp);
! 722: if(matriz.Sdir_imp != NULL) grado->Sdir_imp = InversoNormalizado(dim, pasos->Sdir_imp);
! 723: if(matriz.Spilaimp != NULL) grado->Spilaimp = InversoNormalizado(dim, pasos->Spilaimp);
! 724: if(matriz.Sestadoimp != NULL) grado->Sestadoimp = InversoNormalizado(dim, pasos->Sestadoimp);
! 725:
! 726: if(matriz.D != NULL) grado->D = InversoNormalizado(dim, pasos->D);
! 727: }
! 728:
! 729:
! 730: /* esta función calcula el acoplamiento de cada matriz de dependencias */
! 731:
! 732: void CalcularAcoplamiento(parametromatriz *acoplamiento)
! 733: {
! 734: if(matriz.Ddatoexp != NULL) acoplamiento->Ddatoexp = Acoplamiento(matriz.Ddatoexp);
! 735: if(matriz.Ddir_exp != NULL) acoplamiento->Ddir_exp = Acoplamiento(matriz.Ddir_exp);
! 736: if(matriz.Dpilaexp != NULL) acoplamiento->Dpilaexp = Acoplamiento(matriz.Dpilaexp);
! 737: if(matriz.Destadoexp != NULL) acoplamiento->Destadoexp = Acoplamiento(matriz.Destadoexp);
! 738:
! 739: if(matriz.Ddatoimp != NULL) acoplamiento->Ddatoimp = Acoplamiento(matriz.Ddatoimp);
! 740: if(matriz.Ddir_imp != NULL) acoplamiento->Ddir_imp = Acoplamiento(matriz.Ddir_imp);
! 741: if(matriz.Dpilaimp != NULL) acoplamiento->Dpilaimp = Acoplamiento(matriz.Dpilaimp);
! 742: if(matriz.Destadoimp != NULL) acoplamiento->Destadoimp = Acoplamiento(matriz.Destadoimp);
! 743:
! 744: if(matriz.ADdatoexp != NULL) acoplamiento->ADdatoexp = Acoplamiento(matriz.ADdatoexp);
! 745: if(matriz.ADdir_exp != NULL) acoplamiento->ADdir_exp = Acoplamiento(matriz.ADdir_exp);
! 746: if(matriz.ADpilaexp != NULL) acoplamiento->ADpilaexp = Acoplamiento(matriz.ADpilaexp);
! 747: if(matriz.ADestadoexp != NULL) acoplamiento->ADestadoexp = Acoplamiento(matriz.ADestadoexp);
! 748:
! 749: if(matriz.ADdatoimp != NULL) acoplamiento->ADdatoimp = Acoplamiento(matriz.ADdatoimp);
! 750: if(matriz.ADdir_imp != NULL) acoplamiento->ADdir_imp = Acoplamiento(matriz.ADdir_imp);
! 751: if(matriz.ADpilaimp != NULL) acoplamiento->ADpilaimp = Acoplamiento(matriz.ADpilaimp);
! 752: if(matriz.ADestadoimp != NULL) acoplamiento->ADestadoimp = Acoplamiento(matriz.ADestadoimp);
! 753:
! 754: if(matriz.Sdatoexp != NULL) acoplamiento->Sdatoexp = Acoplamiento(matriz.Sdatoexp);
! 755: if(matriz.Sdir_exp != NULL) acoplamiento->Sdir_exp = Acoplamiento(matriz.Sdir_exp);
! 756: if(matriz.Spilaexp != NULL) acoplamiento->Spilaexp = Acoplamiento(matriz.Spilaexp);
! 757: if(matriz.Sestadoexp != NULL) acoplamiento->Sestadoexp = Acoplamiento(matriz.Sestadoexp);
! 758:
! 759: if(matriz.Sdatoimp != NULL) acoplamiento->Sdatoimp = Acoplamiento(matriz.Sdatoimp);
! 760: if(matriz.Sdir_imp != NULL) acoplamiento->Sdir_imp = Acoplamiento(matriz.Sdir_imp);
! 761: if(matriz.Spilaimp != NULL) acoplamiento->Spilaimp = Acoplamiento(matriz.Spilaimp);
! 762: if(matriz.Sestadoimp != NULL) acoplamiento->Sestadoimp = Acoplamiento(matriz.Sestadoimp);
! 763:
! 764: if(matriz.D != NULL) acoplamiento->D = (double) Acoplamiento(matriz.D);
! 765: }
! 766:
! 767:
! 768:
! 769: /* esta función reserva memoria para salvar el histograma de pasos de computación */
! 770: /* asociado a la matriz de dependencias de datos D (no el resto) */
! 771:
! 772: void CrearHistogramaPasos()
! 773: {
! 774: char mensaje[MAX_LINE];
! 775:
! 776: distribucionpasos = calloc(configuracion.ventana+1, sizeof(unsigned long));
! 777: if (distribucionpasos == NULL)
! 778: {
! 779: sprintf(mensaje, "[CrearHistogramaPasos] Memoria insuficiente");
! 780: Notificar(mensaje, ERROR_SALIR, ECO_NO);
! 781: /* el programa finaliza si no hay memoria suficiente */
! 782: }
! 783: }
! 784:
! 785:
! 786: /* inicia el histograma a 0 (con la reserva de calloc no es necesario) */
! 787:
! 788: void IniciarHistogramaPasos()
! 789: {
! 790: unsigned int i;
! 791:
! 792: for(i=0; i<configuracion.ventana; i++) distribucionpasos[i] = 0;
! 793: }
! 794:
! 795:
! 796: /* libera la memoria reservada para el histograma */
! 797:
! 798: void LiberarMemoriaHistogramaPasos()
! 799: {
! 800: free(distribucionpasos);
! 801: }
! 802:
! 803:
! 804: /* actualiza los datos del histograma */
! 805:
! 806: void ActualizarHistogramaPasos()
! 807: {
! 808: distribucionpasos[(unsigned int)pasos->D]++;
! 809: }
! 810:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>