/DARQ/practica4/gauss.c

https://github.com/adgllorente/university · C · 156 lines · 95 code · 24 blank · 37 comment · 15 complexity · a91fcdebb092a8c9e846caa885963908 MD5 · raw file

  1. /*
  2. * Fichero: gauss.c
  3. * Version: 1.3 - Dic 2010
  4. *
  5. * Adaptación de gauss.c (CS252, Spring 1994)
  6. *
  7. * Pablo Ibáñez
  8. * Jesús Alastruey
  9. */
  10. #include <stdio.h>
  11. #include <unistd.h>
  12. #include <stdlib.h>
  13. #include <sys/times.h>
  14. #include <time.h>
  15. #include <limits.h>
  16. #include <math.h>
  17. /* No hay que cambiar MAXSIZE en cada ejecución (se define constante)
  18. * por tanto, no es necesario recompilar para ejecutar
  19. * el programa con distintos tamaños de problema (matriz, vector)
  20. */
  21. #define MAXSIZE 4104
  22. double A[MAXSIZE][MAXSIZE];
  23. double P[MAXSIZE];
  24. double B[MAXSIZE];
  25. int
  26. main(int argc, char *argv[])
  27. {
  28. int r, s, i, j, intervalos;
  29. int repeat, limit, m_size;
  30. struct tms time_info;
  31. clock_t user0, user1, sample_cpu, sample_elapsed;
  32. clock_t total = 0, total_sqrd = 0;
  33. clock_t tinicio, tfinal, ttotal = 0;
  34. clock_t etime0, etime1;
  35. float timer_resolution;
  36. float loop_mean, loop_var, test_mean, loop_std_ratio_c;
  37. if (argc < 4) {
  38. printf("Uso:%s <tamaño-matriz> <numero-de-iteraciones> <numero-de-pruebas>\n", argv[0]);
  39. exit(-1);
  40. }
  41. m_size = atoi(argv[1]);
  42. if (m_size > MAXSIZE) {
  43. fprintf(stderr,"ERROR: el tamaño de la matriz (%d) debe ser menor que MAXSIZE (%d)\n", m_size, MAXSIZE);
  44. exit(1);
  45. }
  46. limit = atoi(argv[2]);
  47. repeat = atoi(argv[3]);
  48. if ((limit < 1) || (repeat < 1)) {
  49. fprintf(stderr,"ERROR: el número de iteraciones y el de pruebas debe ser mayor que 0\n");
  50. exit(1);
  51. }
  52. /* Inicializacion */
  53. for (i = 0; i < m_size ;i++) {
  54. B[i] = (double) i + 4.0;
  55. P[i] = (double) i * 2.0;
  56. for (j = 0; j < m_size ; j++) {
  57. A[i][j] = (double) i + (double) j;
  58. }
  59. }
  60. /*
  61. * timer_resolution = resolucion en microsegundos del temporizador del computador
  62. * (tiempo en milisegundos entre dos ticks del temporizador)
  63. * Se calcula a partir del nº de intervalos que el temporizador cuenta cada segundo.
  64. * Para saber este nº de intervalos hay que usar la llamada sysconf(_SC_CLK_TCK).
  65. * El programa realiza esta llamada e inicializa la variable timer_resolution.
  66. */
  67. intervalos = sysconf(_SC_CLK_TCK);
  68. timer_resolution = 1000000.0/intervalos;
  69. printf ("\n******** Datos ********\n");
  70. printf("Resolucion del temporizador: %7.1f usg (%d intervalos/seg)\n", timer_resolution, intervalos);
  71. printf("Tamaño_matriz, limit, repeat: %dx%d, %d, %d\n", m_size, m_size, limit, repeat);
  72. /*printf("Tamaño de float: %d\n", sizeof(float)); */
  73. printf("Ejecutando gauss v1.3.\n\n");
  74. /* Inicio del cálculo del tiempo de ejecución de todos los bucles */
  75. times(&time_info); /* man -s2 times */
  76. tinicio = time_info.tms_utime;
  77. /* Ejecuta el experimento "repeat" veces */
  78. for (r = 0; r < repeat; r++)
  79. {
  80. /* Ponemos en marcha el cronometro */
  81. etime0 = times(&time_info);
  82. //user0 = time_info.tms_utime + time_info.tms_stime;
  83. user0 = time_info.tms_utime;
  84. for (s = 0; s < limit; s++)
  85. {
  86. /* Impide optimizaciones agresivas del compilador */
  87. A[0][0] = 0.0;
  88. /* Estos dos bucles anidados son que queremos medir: L/U */
  89. for (i = 0; i < m_size; i++)
  90. {
  91. for (j = 0; j < m_size; j++)
  92. A[i][j] = A[i][j] - P[i]*B[j];
  93. } /* Fin L/U */
  94. } /* Fin s */
  95. //sleep(1);
  96. /* Paramos el cronometro */
  97. etime1 = times(&time_info);
  98. //user1 = time_info.tms_utime + time_info.tms_stime;
  99. user1 = time_info.tms_utime;
  100. sample_cpu = user1 - user0;
  101. sample_elapsed = etime1 - etime0;
  102. printf("*** Test %02d = %8.3f usg (%8.3f)\n", r+1,
  103. sample_cpu*timer_resolution/limit,
  104. sample_elapsed*timer_resolution/limit);
  105. if (sample_cpu == 0)
  106. printf("AVISO: tiempo de ejecución menor que la resolución del reloj\n");
  107. else if (sample_cpu < 20)
  108. printf("AVISO: tiempo de ejecución (%4.2f usg) menor que 20 ticks del reloj (%4.2f usg)\n", sample_cpu*timer_resolution, 20.0*timer_resolution);
  109. total += sample_cpu;
  110. total_sqrd += (sample_cpu * sample_cpu);
  111. } /* fin repeat */
  112. /* Cálculo del tiempo de ejecución de todos los bucles */
  113. times(&time_info);
  114. tfinal = time_info.tms_utime;
  115. //tfinal = time_info.tms_utime + time_info.tms_stime;
  116. ttotal = tfinal - tinicio;
  117. /* Cálculo de la varianza y desviación estándar
  118. * de las medidas obtenidas por el bucle repeat */
  119. /* VAR[X] = E[X^2] - E[X]^2 */
  120. /* STD[X] = sqrt(VAR[X]) */
  121. loop_mean = (float) total / repeat;
  122. loop_var = ((float) total_sqrd / repeat) - (loop_mean * loop_mean);
  123. loop_std_ratio_c = loop_var / (loop_mean*loop_mean);
  124. if (loop_std_ratio_c > 0.0025)
  125. printf("AVISO: Varianza de las mediciones demasiado alta\n");
  126. test_mean = loop_mean / limit;
  127. printf("\n******** Resultados ********\n");
  128. printf("Tiempo medio de ejecución de L/U = %8.3f usg\n", test_mean*timer_resolution);
  129. printf("Tiempo medio de ejecución de limit = %8.0f usg\n", loop_mean*timer_resolution);
  130. printf("Tiempo total de ejecución de repeat = %8.0f usg\n\n", ttotal*timer_resolution);
  131. exit(0);
  132. }