This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR fortran/41157 -- dtime gives inconsistent results.


Here's a patch for fortran/41157.  dtime is documented
to return the execution since its last invocation.  For
x reasons that I don't fully understand, the current
implementation of dtime seems to skip saving the current
execution time on every other invocation.


For an unpatched gfortran, this code

   program test_dtime
   implicit none
   integer :: i, k
   real, dimension(2) :: tarray
   real result, accum, x
   accum = 0.e0
   do k=1, 10
      call loop(k, x)
      call dtime(tarray, result)
      print '(4F10.6)', tarray, result, x
      accum = accum + tarray(1)
   end do
   print '(''accum ='', F10.5)', accum
   end program test_dtime

   subroutine loop(k, x)
   integer, intent(in) :: k
   real, intent(out) :: x
   x = 1.
   do i = 1, 10000000
      x = sin(x * i + 1.)
   end do 
   x = x / k
   end subroutine loop

REMOVE:kargl[310] ./z
  0.442741  0.000000  0.442741  0.927705
  0.442212  0.000000  0.442212  0.463853
  0.884233  0.000000  0.884233  0.309235
  0.884425  0.000000  0.884425  0.231926
  1.326463  0.000000  1.326463  0.185541
  1.326812  0.000000  1.326812  0.154618
  1.768775  0.000000  1.768775  0.132529
  1.768707  0.000000  1.768707  0.115963
  2.209823  0.000000  2.209823  0.103078
  2.209864  0.000000  2.209864  0.092771
accum =  13.26406

The first column should be 0.44xxx.  The second column is
0.00000 and the third column is the sum of the first two.
The last column is the output from the loop() to prevent
the optimizer from removing the call to loop().

While a patched gfortran now yields

REMOVE:kargl[299] ./z
  0.441574  0.000000  0.441574  0.927705
  0.441296  0.000000  0.441296  0.463853
  0.441349  0.000000  0.441349  0.309235
  0.441090  0.000000  0.441090  0.231926
  0.441855  0.000000  0.441855  0.185541
  0.442233  0.000000  0.442233  0.154618
  0.442404  0.000000  0.442404  0.132529
  0.442425  0.000000  0.442425  0.115963
  0.442323  0.000000  0.442323  0.103078
  0.441952  0.000000  0.441952  0.092771
accum =   4.41850

2009-08-24  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/41157
	* dtime.c (dtime_sub): Fix computing time increment.
	* time_1.h: Add <sys/types.h> header.  Use RUSAGE_SELF macro instead
	of a hardcoded 0.

OK for trunk and 4.4?
-- 
Steve
Index: dtime.c
===================================================================
--- dtime.c	(revision 151026)
+++ dtime.c	(working copy)
@@ -38,9 +38,10 @@ iexport_proto(dtime_sub);
 void
 dtime_sub (gfc_array_r4 *t, GFC_REAL_4 *result)
 {
-  static GFC_REAL_4 tu = 0.0, ts = 0.0, tt = 0.0;
   GFC_REAL_4 *tp;
   long user_sec, user_usec, system_sec, system_usec;
+  static long us = 0, uu = 0, ss = 0 , su = 0;
+  GFC_REAL_4 tu, ts, tt;
 
   if (((GFC_DESCRIPTOR_EXTENT(t,0))) < 2)
     runtime_error ("Insufficient number of elements in TARRAY.");
@@ -48,15 +49,19 @@ dtime_sub (gfc_array_r4 *t, GFC_REAL_4 *
   __gthread_mutex_lock (&dtime_update_lock);
   if (__time_1 (&user_sec, &user_usec, &system_sec, &system_usec) == 0)
     {
-      tu = (GFC_REAL_4)(user_sec + 1.e-6 * user_usec) - tu;
-      ts = (GFC_REAL_4)(system_sec + 1.e-6 * system_usec) - ts;
+      tu = (GFC_REAL_4) ((user_sec - us) + 1.e-6 * (user_usec - uu));
+      ts = (GFC_REAL_4) ((system_sec - ss) + 1.e-6 * (system_usec - su));
       tt = tu + ts;
+      us = user_sec;
+      uu = user_usec;
+      ss = system_sec;
+      su = system_usec;
     }
   else
     {
-      tu = (GFC_REAL_4)-1.0;
-      ts = (GFC_REAL_4)-1.0;
-      tt = (GFC_REAL_4)-1.0;
+      tu = -1;
+      ts = -1;
+      tt = -1;
     }
 
   tp = t->data;
Index: time_1.h
===================================================================
--- time_1.h	(revision 151026)
+++ time_1.h	(working copy)
@@ -51,6 +51,10 @@ see the files COPYING3 and COPYING.RUNTI
 #  endif
 #endif
 
+#ifdef HAVE_SYS_TYPES_H
+     #include <sys/types.h>
+#endif
+
 /* The most accurate way to get the CPU time is getrusage (). */
 #if defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
 #  include <sys/resource.h>
@@ -112,7 +116,7 @@ __time_1 (long *user_sec, long *user_use
 {
 #if defined (HAVE_GETRUSAGE) && defined (HAVE_SYS_RESOURCE_H)
   struct rusage usage;
-  getrusage (0, &usage);
+  getrusage (RUSAGE_SELF, &usage);
 
   *user_sec = usage.ru_utime.tv_sec;
   *user_usec = usage.ru_utime.tv_usec;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]