1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This file is part of Gromacs Copyright (c) 1991-2006
5 * David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * To help us fund GROMACS development, we humbly ask that you cite
13 * the research papers on the package. Check out http://www.gromacs.org
16 * Gnomes, ROck Monsters And Chili Sauce
18 #include "gromacs/timing/cyclecounter.h"
25 #ifdef HAVE_SYS_TIME_H
33 /*! \brief Calculate number of seconds per cycle tick on host
35 * This routine runs a timer loop to calibrate the number of
36 * seconds per the units returned fro gmx_cycles_read().
38 * \param sampletime Minimum real sample time. It takes some trial-and-error
39 * to find the correct delay loop size, so the total runtime of
40 * this routine is about twice this time.
41 * \return Number of seconds per cycle unit. If it is not possible to
42 * calculate on this system (for whatever reason) the return value
43 * will be -1, so check that it is positive before using it.
46 gmx_cycles_calibrate(double sampletime)
50 /* Windows does not have gettimeofday, but it provides a special
51 * routine that returns the cycle counter frequency.
55 QueryPerformanceFrequency(&i);
57 return 1.0/((double) i.QuadPart);
58 /* end of MS Windows implementation */
60 #elif (defined HAVE_GETTIMEOFDAY)
62 /* generic implementation with gettimeofday() */
63 struct timeval t1, t2;
65 double timediff, cyclediff;
66 double d = 0.1; /* Dummy variable so we don't optimize away delay loop */
69 if (!gmx_cycles_have_counter())
74 #if (defined(__alpha__) || defined(__alpha))
75 /* Alpha cannot count to more than 4e9, but I don't expect
76 * that the architecture will go over 2GHz before it dies, so
77 * up to 2.0 seconds of sampling should be safe.
85 /* Start a timing loop. We want this to be largely independent
86 * of machine speed, so we need to start with a very small number
87 * of iterations and repeat it until we reach the requested time.
89 * We call gettimeofday an extra time at the start to avoid cache misses.
91 gettimeofday(&t1, NULL);
92 gettimeofday(&t1, NULL);
93 c1 = gmx_cycles_read();
97 /* just a delay loop. To avoid optimizing it away, we calculate a number
98 * that will underflow to zero in most cases. By conditionally adding it
99 * to a result at the end it cannot be removed. n=10000 is arbitrary...
101 for (i = 0; i < 10000; i++)
103 d = d/(1.0+(double)i);
105 /* Read the time again */
106 gettimeofday(&t2, NULL);
107 c2 = gmx_cycles_read();
108 timediff = (double)(t2.tv_sec-t1.tv_sec)+
109 (double)(t2.tv_usec-t1.tv_usec)*1e-6;
111 while (timediff < sampletime);
115 /* Add a very small result so the delay loop cannot be optimized away */
121 /* Return seconds per cycle */
122 return timediff/cyclediff;
125 /* No timing function available */