/home/coin/SVN-release/CoinAll-1.1.0/cppad/cppad/speed_test.hpp

Go to the documentation of this file.
00001 # ifndef CPPAD_SPEED_TEST_INCLUDED
00002 # define CPPAD_SPEED_TEST_INCLUDED
00003 
00004 /* --------------------------------------------------------------------------
00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-07 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the 
00009                     Common Public License Version 1.0.
00010 
00011 A copy of this license is included in the COPYING file of this distribution.
00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00013 -------------------------------------------------------------------------- */
00014 
00015 /*
00016 $begin speed_test$$
00017 $spell
00018         gettimeofday
00019         vec
00020         cppad.hpp
00021         Microsoft
00022         namespace
00023         std
00024         const
00025         cout
00026         ctime
00027         ifdef
00028         const
00029         endif
00030         cpp
00031 $$
00032 
00033 $index speed_test$$
00034 $index test, speed$$
00035 
00036 $section Run One Speed Test and Return Results$$
00037 
00038 $head Syntax$$
00039 $code # include <cppad/speed_test.hpp>$$
00040 $pre
00041 $$
00042 $syntax%%rate_vec% = speed_test(%test%, %size_vec%, %time_min%)%$$
00043 
00044 $head Purpose$$
00045 The $code speed_test$$ function executes a speed test
00046 for various sized problems
00047 and reports the rate of execution.
00048 
00049 $head Motivation$$
00050 It is important to separate small calculation units
00051 and test them individually.
00052 This way individual changes can be tested in the context of the
00053 routine that they are in.
00054 On many machines, accurate timing of a very short execution 
00055 sequences is not possible.
00056 In addition,
00057 there may be set up and tear down time for a test that
00058 we do not really want included in the timing.
00059 For this reason $code speed_test$$
00060 automatically determines how many times to 
00061 repeat the section of the test that we wish to time.
00062 
00063 
00064 $head Include$$
00065 The file $code cppad/speed_test.hpp$$ defines the 
00066 $code speed_test$$ function.
00067 This file is included by $code cppad/cppad.hpp$$
00068 and it can also be included separately with out the rest of 
00069 the $code CppAD$$ routines.
00070 
00071 $head Vector$$
00072 We use $italic Vector$$ to denote a 
00073 $cref/simple vector class/SimpleVector/$$ with elements
00074 of type $code size_t$$.
00075 
00076 $head test$$
00077 The $code speed_test$$ argument $italic test$$ is a function with the syntax
00078 $syntax%
00079         %test%(%size%, %repeat%)
00080 %$$
00081 and its return value is $code void$$.
00082 
00083 $subhead size$$
00084 The $italic test$$ argument $italic size$$ has prototype
00085 $syntax%
00086         size_t %size%
00087 %$$
00088 It specifies the size for this test.
00089 
00090 $subhead repeat$$
00091 The $italic test$$ argument $italic repeat$$ has prototype
00092 $syntax%
00093         size_t %repeat%
00094 %$$
00095 It specifies the number of times to repeat the test.
00096 
00097 $head size_vec$$
00098 The $code speed_test$$ argument $italic size_vec$$ has prototype
00099 $syntax%
00100         const %Vector% &%size_vec%
00101 %$$
00102 This vector determines the size for each of the tests problems.
00103 
00104 $head time_min$$
00105 The argument $italic time_min$$ has prototype
00106 $syntax%
00107         double %time_min%
00108 %$$
00109 It specifies the minimum amount of time in seconds
00110 that the $italic test$$ routine should take.
00111 The $italic repeat$$ argument to $italic test$$ is increased
00112 until this amount of execution time is reached.
00113 
00114 $head rate_vec$$
00115 The return value $italic rate_vec$$ has prototype
00116 $syntax%
00117         %Vector% &%rate_vec%
00118 %$$ 
00119 We use $latex n$$ to denote its size which is the same as
00120 the vector $italic size_vec$$.
00121 For $latex i = 0 , \ldots , n-1$$,
00122 $syntax%
00123         %rate_vec%[%i%]
00124 %$$
00125 is the ratio of $italic repeat$$ divided by time in seconds
00126 for the problem with size $syntax%%size_vec%[%i%]%$$.
00127 
00128 $head Timing$$
00129 If your system supports the unix $code gettimeofday$$ function,
00130 it will be used to measure time. 
00131 Otherwise, 
00132 time is measured by the difference in
00133 $codep
00134         (double) clock() / (double) CLOCKS_PER_SEC
00135 $$
00136 in the context of the standard $code <ctime>$$ definitions.
00137 
00138 $head Example$$
00139 $children%
00140         speed/example/speed_test.cpp
00141 %$$
00142 The section $xref/speed_test.cpp/$$ contains an example and test
00143 of $code speed_test$$.
00144 
00145 $end
00146 -----------------------------------------------------------------------
00147 */
00148 
00149 # include <cstddef>
00150 # include <cmath>
00151 
00152 # include <cppad/check_simple_vector.hpp>
00153 
00154 // undo preprocessor symbols that config.h needs to define
00155 # ifndef CPPAD_CPPAD_INCLUDED
00156 # include <cppad/local/preprocessor.hpp>
00157 # endif
00158 
00159 // use config.h to define CPPAD_GETIMEOFDAY preprocessor symbol
00160 # include <cppad/config.h>
00161 
00162 // Microsoft versions to not run autoconf, so CPPAD_GETTIMEOFDAY may not be
00163 // set to proper value.
00164 # ifdef _MSC_VER
00165 # undef  CPPAD_GETTIMEOFDAY
00166 # define CPPAD_GETTIMEOFDAY 0
00167 # endif
00168 
00169 # if CPPAD_GETTIMEOFDAY
00170 # include <sys/time.h>
00171 # else
00172 # include <ctime>
00173 # endif
00174 
00175 # ifndef CPPAD_NULL
00176 # define CPPAD_NULL     0
00177 # endif
00178 
00179 namespace CppAD { // BEGIN CppAD namespace
00180 
00181 inline double speed_test_second(void)
00182 {
00183 # if CPPAD_GETTIMEOFDAY
00184         struct timeval value;
00185         gettimeofday(&value, CPPAD_NULL);
00186         return double(value.tv_sec) + double(value.tv_usec) * 1e-6;
00187 # else
00188         return (double) clock() / (double) CLOCKS_PER_SEC;
00189 # endif
00190 }
00191 
00192 // implemented as an inline so that can include in multiple link modules
00193 // with this same file
00194 template <class Vector>
00195 inline Vector speed_test( 
00196         void test(size_t size, size_t repeat),
00197         Vector size_vec                      ,
00198         double time_min                      )
00199 {
00200         // check that size_vec is a simple vector with size_t elements
00201         CheckSimpleVector<size_t, Vector>();
00202 
00203         size_t   n = size_vec.size();
00204         Vector rate_vec(n);
00205         size_t i;
00206         for(i = 0; i < n; i++)
00207         {       size_t size   = size_vec[i];
00208                 size_t repeat = 1;
00209                 double s0     = speed_test_second();
00210                 double s1     = speed_test_second();
00211                 while( s1 - s0 < time_min )
00212                 {       repeat = 2 * repeat;
00213                         s0     = speed_test_second();
00214                         test(size, repeat);
00215                         s1     = speed_test_second();
00216                 }
00217                 rate_vec[i] = (size_t)(.5 + repeat / (s1 - s0));
00218         }
00219         return rate_vec;
00220 }
00221 
00222 } // END CppAD namespace
00223 
00224 /*
00225 $begin SpeedTest$$
00226 $spell
00227         cppad.hpp
00228         Microsoft
00229         namespace
00230         std
00231         const
00232         cout
00233         ctime
00234         ifdef
00235         const
00236         endif
00237         cpp
00238 $$
00239 
00240 $index SpeedTest$$
00241 $index test, speed$$
00242 
00243 $section Run One Speed Test and Print Results$$
00244 
00245 $head Syntax$$
00246 
00247 $code # include <cppad/speed_test.hpp>$$
00248 $pre
00249 $$
00250 $syntax%SpeedTest(%Test%, %first%, %inc%, %last%)%$$
00251 
00252 
00253 $head Purpose$$
00254 The $code SpeedTest$$ function executes a speed test
00255 for various sized problems
00256 and reports the results on standard output; i.e. $code std::cout$$.
00257 The size of each test problem is included in its report
00258 (unless $italic first$$ is equal to $italic last$$).
00259 
00260 $head Motivation$$
00261 It is important to separate small calculation units
00262 and test them individually.
00263 This way individual changes can be tested in the context of the
00264 routine that they are in.
00265 On many machines, accurate timing of a very short execution 
00266 sequences is not possible.
00267 In addition,
00268 there may be set up time for a test that
00269 we do not really want included in the timing.
00270 For this reason $code SpeedTest$$
00271 automatically determines how many times to 
00272 repeat the section of the test that we wish to time.
00273 
00274 
00275 $head Include$$
00276 The file $code speed_test.hpp$$ contains the 
00277 $code SpeedTest$$ function.
00278 This file is included by $code cppad/cppad.hpp$$
00279 but it can also be included separately with out the rest of 
00280 the $code CppAD$$ routines.
00281 
00282 $head Test$$
00283 The $code SpeedTest$$ argument $italic Test$$ is a function with the syntax
00284 $syntax%
00285         %name% = %Test%(%size%, %repeat%)
00286 %$$
00287 
00288 $subhead size$$
00289 The $italic Test$$ argument $italic size$$ has prototype
00290 $syntax%
00291         size_t %size%
00292 %$$
00293 It specifies the size for this test.
00294 
00295 $subhead repeat$$
00296 The $italic Test$$ argument $italic repeat$$ has prototype
00297 $syntax%
00298         size_t %repeat%
00299 %$$
00300 It specifies the number of times to repeat the test.
00301 
00302 $subhead name$$
00303 The $italic Test$$ result $italic name$$ has prototype
00304 $syntax%
00305         std::string %name%
00306 %$$
00307 The results for this test are reported on $code std::cout$$
00308 with $italic name$$ as an identifier for the test.
00309 It is assumed that,
00310 for the duration of this call to $code SpeedTest$$,
00311 $italic Test$$ will always return 
00312 the same value for $italic name$$.
00313 If $italic name$$ is the empty string, 
00314 no test name is reported by $code SpeedTest$$.
00315 
00316 $head first$$
00317 The $code SpeedTest$$ argument $italic first$$ has prototype
00318 $syntax%
00319         size_t %first%
00320 %$$
00321 It specifies the size of the first test problem reported by this call to 
00322 $code SpeedTest$$.
00323         
00324 $head last$$
00325 The $code SpeedTest$$ argument $italic last$$ has prototype
00326 $syntax%
00327         size_t %last%
00328 %$$
00329 It specifies the size of the last test problem reported by this call to 
00330 $code SpeedTest$$.
00331 
00332 $head inc$$
00333 The $code SpeedTest$$ argument $italic inc$$ has prototype
00334 $syntax%
00335         int %inc%
00336 %$$
00337 It specifies the increment between problem sizes; i.e.,
00338 all values of $italic size$$ in calls to $italic Test$$ are given by
00339 $syntax%
00340         %size% = %first% + %j% * %inc%
00341 %$$ 
00342 where $italic j$$ is a positive integer.
00343 The increment can be positive or negative but it cannot be zero.
00344 The values $italic first$$, $italic last$$ and $italic inc$$ must 
00345 satisfy the relation
00346 $latex \[
00347         inc * ( last - first ) \geq 0
00348 \] $$
00349 
00350 $head rate$$
00351 The value displayed in the $code rate$$ column on $code std::cout$$
00352 is defined as the value of $italic repeat$$ divided by the 
00353 corresponding elapsed execution time in seconds.
00354 The elapsed execution time is measured by the difference in
00355 $codep
00356         (double) clock() / (double) CLOCKS_PER_SEC
00357 $$
00358 in the context of the standard $code <ctime>$$ definitions.
00359 
00360 
00361 $head Errors$$
00362 If one of the restrictions above is violated,
00363 the CppAD error handler is used to report the error.
00364 You can redefine this action using the instructions in
00365 $xref/ErrorHandler/$$
00366 
00367 $head Example$$
00368 $children%
00369         speed/example/speedtest.cpp
00370 %$$
00371 The section $xref/speedtest.cpp/$$ contains an example usage
00372 of $code SpeedTest$$.
00373 
00374 $end
00375 -----------------------------------------------------------------------
00376 */
00377 // BEGIN PROGRAM
00378 
00379 
00380 # include <string>
00381 # include <iostream>
00382 # include <iomanip>
00383 # include <cppad/local/cppad_assert.hpp>
00384 
00385 namespace CppAD { // BEGIN CppAD namespace
00386 
00387 inline void SpeedTestNdigit(size_t value, size_t &ndigit, size_t &pow10)
00388 {       pow10 = 10;
00389         ndigit       = 1;
00390         while( pow10 <= value )
00391         {       pow10  *= 10;
00392                 ndigit += 1;
00393         }
00394 }
00395 
00396 // implemented as an inline so that can include in multiple link modules
00397 // with this same file
00398 inline void SpeedTest( 
00399         std::string Test(size_t size, size_t repeat),
00400         size_t first,
00401         int    inc,
00402         size_t last
00403 )
00404 {
00405 
00406         using std::cout;
00407         using std::endl;
00408 
00409         size_t    size;
00410         size_t    repeat;
00411         size_t    rate;
00412         size_t    digit;
00413         size_t    ndigit;
00414         size_t    pow10;
00415         size_t    maxSize;
00416         size_t    maxSizeDigit;
00417 
00418         double    s0;
00419         double    s1;
00420 
00421         std::string name;
00422 
00423         CPPAD_ASSERT_KNOWN( 
00424                 inc != 0 && first != 0 && last != 0,
00425                 "inc, first, or last is zero in call to SpeedTest"
00426         );
00427         CPPAD_ASSERT_KNOWN( 
00428                 (inc > 0 && first <= last) || (inc < 0 && first >= last),
00429                 "SpeedTest: increment is positive and first > last or "
00430                 "increment is negative and first < last"
00431         );
00432 
00433         // compute maxSize
00434         maxSize = size = first;
00435         while(  (inc > 0 && size <= last) || (inc < 0 && size >= last) )
00436         {
00437                 if( size > maxSize )
00438                         maxSize = size;
00439 
00440                 // next size
00441                 if( ((int) size) + inc > 0 )
00442                         size += inc;
00443                 else    size  = 0;
00444         }
00445         SpeedTestNdigit(maxSize, maxSizeDigit, pow10);
00446 
00447         size = first;
00448         while(  (inc > 0 && size <= last) || (inc < 0 && size >= last) )
00449         {
00450                 repeat = 1;
00451                 s0     = speed_test_second();
00452                 s1     = speed_test_second();
00453                 while( s1 - s0 < 1. )
00454                 {       repeat = 2 * repeat;
00455                         s0     = speed_test_second();
00456                         name   = Test(size, repeat);
00457                         s1     = speed_test_second();
00458                 }
00459                 rate = (size_t)(.5 + repeat / (s1 - s0));
00460                 
00461 
00462                 if( size == first && name != "" )
00463                         cout << name << endl;
00464 
00465                 if( first != last )
00466                 {
00467                         // convert int(size_t) to avoid warning on _MSC_VER sys
00468                         std::cout << "size = "  << int(size);
00469 
00470                         SpeedTestNdigit(size, ndigit, pow10);
00471                         while( ndigit < maxSizeDigit )
00472                         {       cout << " ";
00473                                 ndigit++;
00474                         }
00475                         cout << " ";
00476                 }
00477 
00478                 cout << "rate = ";
00479                 SpeedTestNdigit(rate, ndigit, pow10);
00480                 while( ndigit > 0 )
00481                 {
00482                         pow10 /= 10;
00483                         digit  = rate / pow10;
00484 
00485                         // convert int(size_t) to avoid warning on _MSC_VER sys
00486                         std::cout << int(digit);
00487 
00488                         rate    = rate % pow10;
00489                         ndigit -= 1;
00490 
00491                         if( (ndigit > 0) && (ndigit % 3 == 0) )
00492                                 cout << ",";
00493                 }
00494                 cout << endl;
00495 
00496                 // next size
00497                 if( ((int) size) + inc > 0 )
00498                         size += inc;
00499                 else    size  = 0;
00500         }
00501         return;
00502 }
00503 
00504 } // END CppAD namespace
00505 
00506 // END PROGRAM
00507 # endif

Generated on Sun Nov 14 14:06:33 2010 for Coin-All by  doxygen 1.4.7