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>