2 * This file is part of the GROMACS molecular simulation package.
4 * This file is part of Gromacs Copyright (c) 1991-2006
5 * David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen.
6 * Copyright (c) 2012, by the GROMACS development team, led by
7 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
8 * others, as listed in the AUTHORS file in the top-level source
9 * directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
42 #ifdef HAVE_SYS_TIME_H
50 #include "gmx_cyclecounter.h"
56 /*! \brief Calculate number of seconds per cycle tick on host
58 * This routine runs a timer loop to calibrate the number of
59 * seconds per the units returned fro gmx_cycles_read().
61 * \param sampletime Minimum real sample time. It takes some trial-and-error
62 * to find the correct delay loop size, so the total runtime of
63 * this routine is about twice this time.
64 * \return Number of seconds per cycle unit. If it is not possible to
65 * calculate on this system (for whatever reason) the return value
66 * will be -1, so check that it is positive before using it.
69 gmx_cycles_calibrate(double sampletime)
73 /* Windows does not have gettimeofday, but it provides a special
74 * routine that returns the cycle counter frequency.
78 QueryPerformanceFrequency(&i);
80 return 1.0/((double) i.QuadPart);
81 /* end of MS Windows implementation */
83 #elif (defined HAVE_GETTIMEOFDAY)
85 /* generic implementation with gettimeofday() */
88 double timediff,cyclediff;
89 double d=0.1; /* Dummy variable so we don't optimize away delay loop */
92 if(!gmx_cycles_have_counter())
97 #if (defined(__alpha__) || defined(__alpha))
98 /* Alpha cannot count to more than 4e9, but I don't expect
99 * that the architecture will go over 2GHz before it dies, so
100 * up to 2.0 seconds of sampling should be safe.
108 /* Start a timing loop. We want this to be largely independent
109 * of machine speed, so we need to start with a very small number
110 * of iterations and repeat it until we reach the requested time.
112 * We call gettimeofday an extra time at the start to avoid cache misses.
114 gettimeofday(&t1,NULL);
115 gettimeofday(&t1,NULL);
116 c1=gmx_cycles_read();
120 /* just a delay loop. To avoid optimizing it away, we calculate a number
121 * that will underflow to zero in most cases. By conditionally adding it
122 * to a result at the end it cannot be removed. n=10000 is arbitrary...
126 /* Read the time again */
127 gettimeofday(&t2,NULL);
128 c2=gmx_cycles_read();
129 timediff=(double)(t2.tv_sec-t1.tv_sec)+
130 (double)(t2.tv_usec-t1.tv_usec)*1e-6;
132 while( timediff < sampletime );
136 /* Add a very small result so the delay loop cannot be optimized away */
142 /* Return seconds per cycle */
143 return timediff/cyclediff;
146 /* No timing function available */