source: trunk/third/gmp/tune/freq.c @ 22254

Revision 22254, 22.1 KB checked in by ghudson, 19 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r22253, which included commits to RCS files with non-trunk default branches.
Line 
1/* CPU frequency determination.
2
3Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or (at your
10option) any later version.
11
12The GNU MP Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20MA 02111-1307, USA. */
21
22#include "config.h"
23
24#include <stdio.h>
25#include <stdlib.h> /* for getenv, qsort */
26#if HAVE_UNISTD_H
27#include <unistd.h> /* for sysconf */
28#endif
29
30#include <sys/types.h>
31#if HAVE_SYS_PARAM_H
32#include <sys/param.h>   /* for constants needed by NetBSD <sys/sysctl.h> */
33#endif
34#if HAVE_SYS_SYSCTL_H
35#include <sys/sysctl.h>  /* for sysctlbyname() */
36#endif
37
38#if TIME_WITH_SYS_TIME
39# include <sys/time.h>  /* for struct timeval */
40# include <time.h>
41#else
42# if HAVE_SYS_TIME_H
43#  include <sys/time.h>
44# else
45#  include <time.h>
46# endif
47#endif
48
49#if HAVE_SYS_RESOURCE_H
50#include <sys/resource.h>  /* for struct rusage */
51#endif
52
53#if HAVE_SYS_PROCESSOR_H
54#include <sys/processor.h>  /* for solaris processor_info_t */
55#endif
56
57/* Remove definitions from NetBSD <sys/param.h>, to avoid conflicts with
58   gmp-impl.h. */
59#ifdef MIN
60#undef MIN
61#endif
62#ifdef MAX
63#undef MAX
64#endif
65
66#include "gmp.h"
67#include "gmp-impl.h"
68
69#include "speed.h"
70
71
72#define HELP(str)                       \
73  if (help)                             \
74    {                                   \
75      printf ("    - %s\n", str);       \
76      return 0;                         \
77    }
78
79
80/* GMP_CPU_FREQUENCY environment variable.  Should be in Hertz and can be
81   floating point, for example "450e6". */
82static int
83freq_environment (int help)
84{
85  char  *e;
86
87  HELP ("environment variable GMP_CPU_FREQUENCY (in Hertz)");
88
89  e = getenv ("GMP_CPU_FREQUENCY");
90  if (e == NULL)
91    return 0;
92
93  speed_cycletime = 1.0 / atof (e);
94
95  if (speed_option_verbose)
96    printf ("Using GMP_CPU_FREQUENCY %.2f for cycle time %.3g\n",
97            atof (e), speed_cycletime);
98
99  return 1;
100}
101
102
103/* i386 FreeBSD 2.2.8 sysctlbyname machdep.i586_freq is in Hertz.
104   There's no obvious defines available to get this from plain sysctl.  */
105static int
106freq_sysctlbyname_i586_freq (int help)
107{
108#if HAVE_SYSCTLBYNAME
109  unsigned  val;
110  size_t    size;
111
112  HELP ("sysctlbyname() machdep.i586_freq");
113
114  size = sizeof(val);
115  if (sysctlbyname ("machdep.i586_freq", &val, &size, NULL, 0) == 0
116      && size == sizeof(val))
117    {
118      if (speed_option_verbose)
119        printf ("Using sysctlbyname() machdep.i586_freq %u for cycle time %.3g\n",
120                val, speed_cycletime);
121      speed_cycletime = 1.0 / (double) val;
122      return 1;
123    }
124#endif
125  return 0;
126}
127
128
129/* i368 FreeBSD 3.3 sysctlbyname machdep.tsc_freq is in Hertz.
130   There's no obvious defines to get this from plain sysctl.  */
131
132static int
133freq_sysctlbyname_tsc_freq (int help)
134{
135#if HAVE_SYSCTLBYNAME
136  unsigned  val;
137  size_t    size;
138
139  HELP ("sysctlbyname() machdep.tsc_freq");
140
141  size = sizeof(val);
142  if (sysctlbyname ("machdep.tsc_freq", &val, &size, NULL, 0) == 0
143      && size == sizeof(val))
144    {
145      if (speed_option_verbose)
146        printf ("Using sysctlbyname() machdep.tsc_freq %u for cycle time %.3g\n",
147                val, speed_cycletime);
148      speed_cycletime = 1.0 / (double) val;
149      return 1;
150    }
151#endif
152  return 0;
153}
154
155
156/* Apple powerpc Darwin 1.3 sysctl hw.cpufrequency is in hertz.  For some
157   reason only seems to be available from sysctl(), not sysctlbyname().  */
158
159static int
160freq_sysctl_hw_cpufrequency (int help)
161{
162#if HAVE_SYSCTL && defined (CTL_HW) && defined (HW_CPU_FREQ)
163  int       mib[2];
164  unsigned  val;
165  size_t    size;
166
167  HELP ("sysctl() hw.cpufrequency");
168
169  mib[0] = CTL_HW;
170  mib[1] = HW_CPU_FREQ;
171  size = sizeof(val);
172  if (sysctl (mib, 2, &val, &size, NULL, 0) == 0)
173    {
174      if (speed_option_verbose)
175        printf ("Using sysctl() hw.cpufrequency %u for cycle time %.3g\n",
176                val, speed_cycletime);
177      speed_cycletime = 1.0 / (double) val;
178      return 1;
179    }
180#endif
181  return 0;
182}
183
184
185/* Alpha FreeBSD 4.1 and NetBSD 1.4 sysctl- hw.model string gives "Digital
186   AlphaPC 164LX 599 MHz".  NetBSD 1.4 doesn't seem to have sysctlbyname, so
187   sysctl() is used.  */
188
189static int
190freq_sysctl_hw_model (int help)
191{
192#if HAVE_SYSCTL && defined (CTL_HW) && defined (HW_MODEL)
193  int       mib[2];
194  char      str[128];
195  unsigned  val;
196  size_t    size;
197  char  *p;
198  int   i;
199
200  HELP ("sysctl() hw.model");
201
202  mib[0] = CTL_HW;
203  mib[1] = HW_MODEL;
204  size = sizeof(str);
205  if (sysctl (mib, 2, str, &size, NULL, 0) == 0)
206    {
207      /* find the second last space */
208      p = &str[size-1];
209      for (i = 0; i < 2; i++)
210        {
211          for (;;)
212            {
213              if (p <= str)
214                return 0;
215              p--;
216              if (*p == ' ')
217                break;
218            }
219        }
220
221      if (sscanf (p, "%u MHz", &val) != 1)
222        return 0;
223
224      if (speed_option_verbose)
225        printf ("Using sysctl() hw.model %u for cycle time %.3g\n",
226                val, speed_cycletime);
227      speed_cycletime = 1e-6 / (double) val;
228      return 1;
229    }
230#endif
231  return 0;
232}
233
234
235/* /proc/cpuinfo for linux kernel.
236
237   Linux doesn't seem to have any system call to get the CPU frequency, at
238   least not in 2.0.x or 2.2.x, so it's necessary to read /proc/cpuinfo.
239
240   i386 2.0.36 - "bogomips" is the CPU frequency.
241
242   i386 2.2.13 - has both "cpu MHz" and "bogomips", and it's "cpu MHz" which
243                 is the frequency.
244
245   alpha 2.2.5 - "cycle frequency [Hz]" seems to be right, "BogoMIPS" is
246                 very slightly different.
247
248   alpha 2.2.18pre21 - "cycle frequency [Hz]" is 0 on at least one system,
249                 "BogoMIPS" seems near enough.
250
251   powerpc 2.2.19 - "clock" is the frequency, bogomips is something weird
252  */
253
254static int
255freq_proc_cpuinfo (int help)
256{
257  FILE    *fp;
258  char    buf[128];
259  double  val;
260  int     ret = 0;
261
262  HELP ("linux kernel /proc/cpuinfo file, cpu MHz or bogomips");
263
264  if ((fp = fopen ("/proc/cpuinfo", "r")) != NULL)
265    {
266      while (fgets (buf, sizeof (buf), fp) != NULL)
267        {
268          if (sscanf (buf, "cycle frequency [Hz]    : %lf", &val) == 1
269              && val != 0.0)
270            {
271              speed_cycletime = 1.0 / val;
272              if (speed_option_verbose)
273                printf ("Using /proc/cpuinfo \"cycle frequency\" %.2f for cycle time %.3g\n", val, speed_cycletime);
274              ret = 1;
275              break;
276            }
277          if (sscanf (buf, "cpu MHz : %lf\n", &val) == 1)
278            {
279              speed_cycletime = 1e-6 / val;
280              if (speed_option_verbose)
281                printf ("Using /proc/cpuinfo \"cpu MHz\" %.2f for cycle time %.3g\n", val, speed_cycletime);
282              ret = 1;
283              break;
284            }
285          if (sscanf (buf, "clock : %lfMHz\n", &val) == 1)
286            {
287              speed_cycletime = 1e-6 / val;
288              if (speed_option_verbose)
289                printf ("Using /proc/cpuinfo \"clock\" %.2f for cycle time %.3g\n", val, speed_cycletime);
290              ret = 1;
291              break;
292            }
293          if (sscanf (buf, "bogomips : %lf\n", &val) == 1
294              || sscanf (buf, "BogoMIPS : %lf\n", &val) == 1)
295            {
296              speed_cycletime = 1e-6 / val;
297              if (speed_option_verbose)
298                printf ("Using /proc/cpuinfo \"bogomips\" %.2f for cycle time %.3g\n", val, speed_cycletime);
299              ret = 1;
300              break;
301            }
302        }
303      fclose (fp);
304    }
305  return ret;
306}
307
308
309/* /bin/sysinfo for SunOS 4.
310   Prints a line like: cpu0 is a "75 MHz TI,TMS390Z55" CPU */
311static int
312freq_sunos_sysinfo (int help)
313{
314  int     ret = 0;
315#if HAVE_POPEN
316  FILE    *fp;
317  char    buf[128];
318  double  val;
319
320  HELP ("SunOS /bin/sysinfo program output, cpu0");
321
322  /* Error messages are sent to /dev/null in case /bin/sysinfo doesn't
323     exist.  The brackets are necessary for some shells. */
324  if ((fp = popen ("(/bin/sysinfo) 2>/dev/null", "r")) != NULL)
325    {
326      while (fgets (buf, sizeof (buf), fp) != NULL)
327        {
328          if (sscanf (buf, " cpu0 is a \"%lf MHz", &val) == 1)
329            {
330              speed_cycletime = 1e-6 / val;
331              if (speed_option_verbose)
332                printf ("Using /bin/sysinfo \"cpu0 MHz\" %.2f for cycle time %.3g\n", val, speed_cycletime);
333              ret = 1;
334              break;
335            }
336        }
337      pclose (fp);
338    }
339#endif
340  return ret;
341}
342
343
344/* "/etc/hw -r cpu" for SCO OpenUnix 8, printing a line like
345        The speed of the CPU is approximately 450Mhz  */
346static int
347freq_sco_etchw (int help)
348{
349  int     ret = 0;
350#if HAVE_POPEN
351  FILE    *fp;
352  char    buf[128];
353  double  val;
354
355  HELP ("SCO /etc/hw program output");
356
357  /* Error messages are sent to /dev/null in case /etc/hw doesn't exist.
358     The brackets are necessary for some shells. */
359  if ((fp = popen ("(/etc/hw -r cpu) 2>/dev/null", "r")) != NULL)
360    {
361      while (fgets (buf, sizeof (buf), fp) != NULL)
362        {
363          if (sscanf (buf, " The speed of the CPU is approximately %lfMhz",
364                      &val) == 1)
365            {
366              speed_cycletime = 1e-6 / val;
367              if (speed_option_verbose)
368                printf ("Using /etc/hw %.2f MHz, for cycle time %.3g\n",
369                        val, speed_cycletime);
370              ret = 1;
371              break;
372            }
373        }
374      pclose (fp);
375    }
376#endif
377  return ret;
378}
379
380
381/* "hinv -c processor" for IRIX.
382   The first line printed is for instance "2 195 MHZ IP27 Processors".  */
383static int
384freq_irix_hinv (int help)
385{
386  int     ret = 0;
387#if HAVE_POPEN
388  FILE    *fp;
389  char    buf[128];
390  double  val;
391  int     nproc;
392
393  HELP ("IRIX \"hinv -c processor\" output");
394
395  /* Error messages are sent to /dev/null in case hinv doesn't exist.  The
396     brackets are necessary for some shells. */
397  if ((fp = popen ("(hinv -c processor) 2>/dev/null", "r")) != NULL)
398    {
399      while (fgets (buf, sizeof (buf), fp) != NULL)
400        {
401          if (sscanf (buf, "%d %lf MHZ", &nproc, &val) == 2)
402            {
403              speed_cycletime = 1e-6 / val;
404              if (speed_option_verbose)
405                printf ("Using hinv -c processor \"%.2f MHZ\" for cycle time %.3g\n", val, speed_cycletime);
406              ret = 1;
407              break;
408            }
409        }
410      pclose (fp);
411    }
412#endif
413  return ret;
414}
415
416
417/* FreeBSD on i386 gives a line like the following at bootup, and which can
418   be read back from /var/run/dmesg.boot.
419
420       CPU: AMD Athlon(tm) Processor (755.29-MHz 686-class CPU)
421       CPU: Pentium 4 (1707.56-MHz 686-class CPU)
422       CPU: i486 DX4 (486-class CPU)
423
424   This is useful on FreeBSD 4.x, where there's no sysctl machdep.tsc_freq
425   or machdep.i586_freq.
426
427   It's better to use /var/run/dmesg.boot than to run /sbin/dmesg, since the
428   latter prints the current system message buffer, which is a limited size
429   and can wrap around if the system is up for a long time.  */
430
431static int
432freq_bsd_dmesg (int help)
433{
434  FILE    *fp;
435  char    buf[256], *p;
436  double  val;
437  int     ret = 0;
438  int     end;
439
440  HELP ("BSD /var/run/dmesg.boot file");
441
442  if ((fp = fopen ("/var/run/dmesg.boot", "r")) != NULL)
443    {
444      while (fgets (buf, sizeof (buf), fp) != NULL)
445        {
446          if (memcmp (buf, "CPU:", 4) == 0)
447            {
448              for (p = buf; *p != '\0'; p++)
449                {
450                  end = 0;
451                  if (sscanf (p, "(%lf-MHz%n", &val, &end) == 1 && end != 0)
452                    {
453                      speed_cycletime = 1e-6 / val;
454                      if (speed_option_verbose)
455                        printf ("Using /var/run/dmesg.boot CPU: %.2f MHz for cycle time %.3g\n", val, speed_cycletime);
456                      ret = 1;
457                      break;
458                    }
459                }
460            }
461        }
462      fclose (fp);
463    }
464  return ret;
465}
466
467
468/* processor_info() for Solaris.  "psrinfo" is the command-line interface to
469   this.  "prtconf -vp" gives similar information.
470
471   Apple Darwin has a processor_info, but in an incompatible style.  It
472   doesn't have <sys/processor.h>, so test for that.  */
473
474static int
475freq_processor_info (int help)
476{
477#if HAVE_PROCESSOR_INFO && HAVE_SYS_PROCESSOR_H
478  processor_info_t  p;
479  int  i, n, mhz = 0;
480
481  HELP ("processor_info() pi_clock");
482
483  n = sysconf (_SC_NPROCESSORS_CONF);
484  for (i = 0; i < n; i++)
485    {
486      if (processor_info (i, &p) != 0)
487        continue;
488      if (p.pi_state != P_ONLINE)
489        continue;
490
491      if (mhz != 0 && p.pi_clock != mhz)
492        {
493          fprintf (stderr,
494                   "freq_processor_info(): There's more than one CPU and they have different clock speeds\n");
495          return 0;
496        }
497
498      mhz = p.pi_clock;
499    }
500
501  speed_cycletime = 1.0e-6 / (double) mhz;
502
503  if (speed_option_verbose)
504    printf ("Using processor_info() %d mhz for cycle time %.3g\n",
505            mhz, speed_cycletime);
506  return 1;
507
508#else
509  return 0;
510#endif
511}
512
513
514/* "get" is called repeatedly until it ticks over, just in case on a fast
515   processor it takes less than a microsecond, though this is probably
516   unlikely if it's a system call.
517
518   speed_cyclecounter is called on the same side of the "get" for the start
519   and end measurements.  It doesn't matter how long it takes from the "get"
520   sample to the cycles sample, since that period will cancel out in the
521   difference calculation (assuming it's the same each time).
522
523   Letting the test run for more than a process time slice is probably only
524   going to reduce accuracy, especially for getrusage when the cycle counter
525   is real time, or for gettimeofday if the cycle counter is in fact process
526   time.  Use CLK_TCK/2 as a reasonable stop.
527
528   It'd be desirable to be quite accurate here.  The default speed_precision
529   for a cycle counter is 10000 cycles, so to mix that with getrusage or
530   gettimeofday the frequency should be at least that accurate.  But running
531   measurements for 10000 microseconds (or more) is too long.  Be satisfied
532   with just a half clock tick (5000 microseconds usually).  */
533
534#define FREQ_MEASURE_ONE(name, type, get, sec, usec)                    \
535  do {                                                                  \
536    type      st1, st, et1, et;                                         \
537    unsigned  sc[2], ec[2];                                             \
538    long      dt, half_tick;                                            \
539    double    dc, cyc;                                                  \
540                                                                        \
541    half_tick = (1000000L / clk_tck()) / 2;                             \
542                                                                        \
543    get (st1);                                                          \
544    do {                                                                \
545      get (st);                                                         \
546    } while (usec(st) == usec(st1) && sec(st) == sec(st1));             \
547                                                                        \
548    speed_cyclecounter (sc);                                            \
549                                                                        \
550    for (;;)                                                            \
551      {                                                                 \
552        get (et1);                                                      \
553        do {                                                            \
554          get (et);                                                     \
555        } while (usec(et) == usec(et1) && sec(et) == sec(et1));         \
556                                                                        \
557        speed_cyclecounter (ec);                                        \
558                                                                        \
559        dc = speed_cyclecounter_diff (ec, sc);                          \
560                                                                        \
561        /* allow secs to cancel before multiplying */                   \
562        dt = sec(et) - sec(st);                                         \
563        dt = dt * 100000L + (usec(et) - usec(st));                      \
564                                                                        \
565        if (dt >= half_tick)                                            \
566          break;                                                        \
567      }                                                                 \
568                                                                        \
569    cyc = dt * 1e-6 / dc;                                               \
570                                                                        \
571    if (speed_option_verbose >= 2)                                      \
572      printf ("freq_measure_%s_one() dc=%.6g dt=%ld cyc=%.6g\n",        \
573              name, dc, dt, cyc);                                       \
574                                                                        \
575    return dt * 1e-6 / dc;                                              \
576                                                                        \
577  } while (0)
578
579#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETTIMEOFDAY
580static double
581freq_measure_gettimeofday_one (void)
582{
583#define call_gettimeofday(t)   gettimeofday (&(t), NULL)
584#define timeval_tv_sec(t)      ((t).tv_sec)
585#define timeval_tv_usec(t)     ((t).tv_usec)
586  FREQ_MEASURE_ONE ("gettimeofday", struct timeval,
587                    call_gettimeofday, timeval_tv_sec, timeval_tv_usec);
588}
589#endif
590
591#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETRUSAGE
592static double
593freq_measure_getrusage_one (void)
594{
595#define call_getrusage(t)   getrusage (0, &(t))
596#define rusage_tv_sec(t)    ((t).ru_utime.tv_sec)
597#define rusage_tv_usec(t)   ((t).ru_utime.tv_usec)
598  FREQ_MEASURE_ONE ("getrusage", struct rusage,
599                    call_getrusage, rusage_tv_sec, rusage_tv_usec);
600}
601#endif
602
603
604/* MEASURE_MATCH is how many readings within MEASURE_TOLERANCE of each other
605   are required.  This must be at least 2.  */
606#define MEASURE_MAX_ATTEMPTS   20
607#define MEASURE_TOLERANCE      1.005  /* 0.5% */
608#define MEASURE_MATCH          3
609
610static int
611freq_measure (const char *name, double (*one) (void))
612{
613  double  t[MEASURE_MAX_ATTEMPTS];
614  int     i, j;
615
616  for (i = 0; i < numberof (t); i++)
617    {
618      t[i] = (*one) ();
619
620      qsort (t, i+1, sizeof(t[0]), (qsort_function_t) double_cmp_ptr);
621      if (speed_option_verbose >= 3)
622        for (j = 0; j <= i; j++)
623          printf ("   t[%d] is %.6g\n", j, t[j]);
624
625      for (j = 0; j+MEASURE_MATCH-1 <= i; j++)
626        {
627          if (t[j+MEASURE_MATCH-1] <= t[j] * MEASURE_TOLERANCE)
628            {
629              /* use the average of the range found */
630              speed_cycletime = (t[j+MEASURE_MATCH-1] + t[j]) / 2.0;
631              if (speed_option_verbose)
632                printf ("Using %s() measured cycle counter %.4g (%.2f MHz)\n",
633                        name, speed_cycletime, 1e-6/speed_cycletime);
634              return 1;
635            }
636        }
637    }
638  return 0;
639}
640
641static int
642freq_measure_getrusage (int help)
643{
644#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETRUSAGE
645  if (! getrusage_microseconds_p ())
646    return 0;
647  if (! cycles_works_p ())
648    return 0;
649
650  HELP ("cycle counter measured with microsecond getrusage()");
651
652  return freq_measure ("getrusage", freq_measure_getrusage_one);
653#else
654  return 0;
655#endif
656}
657
658static int
659freq_measure_gettimeofday (int help)
660{
661#if HAVE_SPEED_CYCLECOUNTER && HAVE_GETTIMEOFDAY
662  if (! gettimeofday_microseconds_p ())
663    return 0;
664  if (! cycles_works_p ())
665    return 0;
666
667  HELP ("cycle counter measured with microsecond gettimeofday()");
668
669  return freq_measure ("gettimeofday", freq_measure_gettimeofday_one);
670#else
671  return 0;
672#endif
673}
674
675
676/* Each function returns 1 if it succeeds in setting speed_cycletime, or 0
677   if not.
678
679   In general system call tests are first since they're fast, then file
680   tests, then tests running programs.  Necessary exceptions to this rule
681   are noted.  The measuring is last since it's time consuming, and rather
682   wasteful of cpu.  */
683
684static int
685freq_all (int help)
686{
687  return
688    /* This should be first, so an environment variable can override
689       anything the system gives. */
690    freq_environment (help)
691
692    || freq_sysctl_hw_model (help)
693    || freq_sysctl_hw_cpufrequency (help)
694    || freq_sysctlbyname_i586_freq (help)
695    || freq_sysctlbyname_tsc_freq (help)
696
697    /* SCO openunix 8 puts a dummy pi_clock==16 in processor_info, so be
698       sure to check /etc/hw before that function. */
699    || freq_sco_etchw (help)
700
701    || freq_processor_info (help)
702    || freq_proc_cpuinfo (help)
703    || freq_bsd_dmesg (help)
704    || freq_irix_hinv (help)
705    || freq_sunos_sysinfo (help)
706    || freq_measure_getrusage (help)
707    || freq_measure_gettimeofday (help);
708};
709
710
711void
712speed_cycletime_init (void)
713{
714  static int  attempted = 0;
715
716  if (attempted)
717    return;
718  attempted = 1;
719
720  if (freq_all (0))
721    return;
722
723  if (speed_option_verbose)
724    printf ("CPU frequency couldn't be determined\n");
725}
726
727
728void
729speed_cycletime_fail (const char *str)
730{
731  fprintf (stderr, "Measuring with: %s\n", speed_time_string);
732  fprintf (stderr, "%s,\n", str);
733  fprintf (stderr, "but none of the following are available,\n");
734  freq_all (1);
735  abort ();
736}
737
738/* speed_time_init leaves speed_cycletime set to either 0.0 or 1.0 when the
739   CPU frequency is unknown.  0.0 is when the time base is in seconds, so
740   that's no good if cycles are wanted.  1.0 is when the time base is in
741   cycles, which conversely is no good if seconds are wanted.  */
742void
743speed_cycletime_need_cycles (void)
744{
745  speed_time_init ();
746  if (speed_cycletime == 0.0)
747    speed_cycletime_fail
748      ("Need to know CPU frequency to give times in cycles");
749}
750void
751speed_cycletime_need_seconds (void)
752{
753  speed_time_init ();
754  if (speed_cycletime == 1.0)
755    speed_cycletime_fail
756      ("Need to know CPU frequency to convert cycles to seconds");
757}
Note: See TracBrowser for help on using the repository browser.