Annotation of ADD_ver_10/Source Code/Source Files/CalculosMatrices.c, revision 1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>