00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00050 #ifndef WINSTL_INCL_WINSTL_PERFORMANCE_HPP_PERFORMANCE_COUNTER
00051 #define WINSTL_INCL_WINSTL_PERFORMANCE_HPP_PERFORMANCE_COUNTER
00052
00053 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00054 # define WINSTL_VER_WINSTL_PERFORMANCE_HPP_PERFORMANCE_COUNTER_MAJOR 4
00055 # define WINSTL_VER_WINSTL_PERFORMANCE_HPP_PERFORMANCE_COUNTER_MINOR 1
00056 # define WINSTL_VER_WINSTL_PERFORMANCE_HPP_PERFORMANCE_COUNTER_REVISION 5
00057 # define WINSTL_VER_WINSTL_PERFORMANCE_HPP_PERFORMANCE_COUNTER_EDIT 31
00058 #endif
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00074 # include <winstl/winstl.h>
00075 #endif
00076
00077 #ifndef STLSOFT_INCL_STLSOFT_UTIL_H_LIMIT_TRAITS
00078 # include <stlsoft/util/limit_traits.h>
00079 #endif
00080 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STATIC_INITIALISERS
00081 # include <stlsoft/util/static_initialisers.hpp>
00082 #endif
00083 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_SIGN_TRAITS
00084
00085 #endif
00086 #ifndef STLSOFT_CF_64BIT_INT_SUPPORT
00087 # ifndef STLSOFT_INCL_STLSOFT_HPP_64BIT_INTEGERS
00088 # include <stlsoft/64bit_integers.hpp>
00089 # endif
00090 #endif
00091
00092
00093
00094
00095
00096 #ifndef _WINSTL_NO_NAMESPACE
00097 # if defined(_STLSOFT_NO_NAMESPACE) || \
00098 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00099
00100 namespace winstl
00101 {
00102 # else
00103
00104
00105 namespace stlsoft
00106 {
00107
00108 namespace winstl_project
00109 {
00110
00111 # endif
00112 #endif
00113
00114
00115
00116
00117
00118
00164 class performance_counter
00165 {
00168 public:
00174 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00175 typedef ws_sint64_t epoch_type;
00176 #else
00177 typedef sinteger64 epoch_type;
00178 #endif
00184 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00185 typedef ws_sint64_t interval_type;
00186 #else
00187 typedef sinteger64 interval_type;
00188 #endif
00190 typedef performance_counter class_type;
00192
00195 public:
00196 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00197 static void class_init()
00198 {
00199 class_type instance;
00200
00201 instance.start();
00202 }
00203 static void class_uninit()
00204 {}
00205
00206 performance_counter()
00207 {}
00208 #endif
00210
00213 public:
00217 void start();
00221 void stop();
00226 void restart();
00228
00231 public:
00233 static epoch_type get_epoch();
00234
00236 static interval_type get_seconds(epoch_type start, epoch_type end);
00238 static interval_type get_milliseconds(epoch_type start, epoch_type end);
00240 static interval_type get_microseconds(epoch_type start, epoch_type end);
00241
00245 interval_type get_period_count() const;
00249 interval_type get_seconds() const;
00253 interval_type get_milliseconds() const;
00257 interval_type get_microseconds() const;
00258
00261 interval_type stop_get_period_count_and_restart();
00262
00265 interval_type stop_get_seconds_and_restart();
00266
00269 interval_type stop_get_milliseconds_and_restart();
00270
00273 interval_type stop_get_microseconds_and_restart();
00275
00278 private:
00279 typedef void (*measure_fn_type)(epoch_type&);
00280
00281 static interval_type frequency_();
00282 static interval_type query_frequency_();
00283 static void qpc_(epoch_type &epoch);
00284 static void gtc_(epoch_type &epoch);
00285 static measure_fn_type get_measure_fn_();
00286 static void measure_(epoch_type &epoch);
00288
00291 private:
00292 epoch_type m_start;
00293 epoch_type m_end;
00295 };
00296
00297
00298
00299 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00300 # if !defined(STLSOFT_COMPILER_IS_DMC) && \
00301 ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
00302 _MSC_VER >= 1200)
00303 static stlsoft_ns_qual(class_constructor)<performance_counter> s_performance_counter_class_constructor(&performance_counter::class_init, NULL);
00304 # endif
00305 #endif
00306
00307
00308
00309
00310
00311 #ifdef STLSOFT_UNITTEST
00312 # include "./unittest/performance_counter_unittest_.h"
00313 #endif
00314
00315
00316
00317
00318
00319 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00320
00321 inline performance_counter::interval_type performance_counter::query_frequency_()
00322 {
00323 interval_type frequency;
00324
00325
00326 if( !::QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&frequency)) ||
00327 frequency == 0)
00328 {
00329
00330
00331 frequency = 1000;
00332 }
00333
00334 return frequency;
00335 }
00336
00337 inline performance_counter::interval_type performance_counter::frequency_()
00338 {
00339 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00340 _MSC_VER >= 1310
00341
00342 # pragma warning(push)
00343 # pragma warning(disable : 4640)
00344 #endif
00345
00346 #if defined(STLSOFT_COMPILER_IS_BORLAND)
00347 interval_type s_frequency = query_frequency_();
00348 #else
00349 static interval_type s_frequency = query_frequency_();
00350 #endif
00351
00352 WINSTL_ASSERT(0 != s_frequency);
00353
00354 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00355 _MSC_VER >= 1310
00356 # pragma warning(pop)
00357 #endif
00358
00359 return s_frequency;
00360 }
00361
00362 inline void performance_counter::qpc_(epoch_type &epoch)
00363 {
00364 static_cast<void>(::QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&epoch)));
00365 }
00366
00367 inline void performance_counter::gtc_(epoch_type &epoch)
00368 {
00369 epoch = static_cast<ws_sint32_t>(::GetTickCount());
00370 }
00371
00372 inline performance_counter::measure_fn_type performance_counter::get_measure_fn_()
00373 {
00374 measure_fn_type fn;
00375 epoch_type frequency;
00376
00377 if(QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&frequency)))
00378 {
00379 fn = qpc_;
00380 }
00381 else
00382 {
00383 fn = gtc_;
00384 }
00385
00386 return fn;
00387 }
00388
00389 inline void performance_counter::measure_(epoch_type &epoch)
00390 {
00391 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00392 _MSC_VER >= 1310
00393
00394 # pragma warning(push)
00395 # pragma warning(disable : 4640)
00396 #endif
00397
00398 static measure_fn_type fn = get_measure_fn_();
00399
00400 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00401 _MSC_VER >= 1310
00402 # pragma warning(pop)
00403 #endif
00404
00405 fn(epoch);
00406 }
00407
00408
00409 inline void performance_counter::start()
00410 {
00411 measure_(m_start);
00412 }
00413
00414 inline void performance_counter::stop()
00415 {
00416 measure_(m_end);
00417 }
00418
00419 inline void performance_counter::restart()
00420 {
00421 measure_(m_start);
00422 m_end = m_start;
00423 }
00424
00425
00426
00427 inline performance_counter::epoch_type performance_counter::get_epoch()
00428 {
00429 epoch_type epoch;
00430
00431 measure_(epoch);
00432
00433 return epoch;
00434 }
00435
00436 inline performance_counter::interval_type performance_counter::get_seconds(performance_counter::epoch_type start, performance_counter::epoch_type end)
00437 {
00438 interval_type period_count = static_cast<interval_type>(end - start);
00439
00440 return period_count / frequency_();
00441 }
00442
00443 inline performance_counter::interval_type performance_counter::get_milliseconds(performance_counter::epoch_type start, performance_counter::epoch_type end)
00444 {
00445 interval_type result;
00446 interval_type count = static_cast<interval_type>(end - start);
00447
00448 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00449 if(count < STLSOFT_GEN_SINT64_SUFFIX(0x20C49BA5E353F7))
00450 #else
00451 if(count < interval_type(0x20C49B, 0xA5E353F7))
00452 #endif
00453 {
00454 result = (count * interval_type(1000)) / frequency_();
00455 }
00456 else
00457 {
00458 result = (count / frequency_()) * interval_type(1000);
00459 }
00460
00461 return result;
00462 }
00463
00464 inline performance_counter::interval_type performance_counter::get_microseconds(performance_counter::epoch_type start, performance_counter::epoch_type end)
00465 {
00466 interval_type result;
00467 interval_type count = static_cast<interval_type>(end - start);
00468
00469 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00470 if(count < STLSOFT_GEN_SINT64_SUFFIX(0x8637BD05AF6))
00471 #else
00472 if(count < interval_type(0x863, 0x7BD05AF6))
00473 #endif
00474 {
00475 result = (count * interval_type(1000000)) / frequency_();
00476 }
00477 else
00478 {
00479 result = (count / frequency_()) * interval_type(1000000);
00480 }
00481
00482 return result;
00483 }
00484
00485 inline performance_counter::interval_type performance_counter::get_period_count() const
00486 {
00487 return static_cast<interval_type>(m_end - m_start);
00488 }
00489
00490 inline performance_counter::interval_type performance_counter::get_seconds() const
00491 {
00492 return get_period_count() / frequency_();
00493 }
00494
00495 inline performance_counter::interval_type performance_counter::get_milliseconds() const
00496 {
00497 interval_type result;
00498 interval_type count = get_period_count();
00499
00500 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00501 if(count < STLSOFT_GEN_SINT64_SUFFIX(0x20C49BA5E353F7))
00502 #else
00503 if(count < interval_type(0x20C49B, 0xA5E353F7))
00504 #endif
00505 {
00506 result = (count * interval_type(1000)) / frequency_();
00507 }
00508 else
00509 {
00510 result = (count / frequency_()) * interval_type(1000);
00511 }
00512
00513 return result;
00514 }
00515
00516 inline performance_counter::interval_type performance_counter::get_microseconds() const
00517 {
00518 interval_type result;
00519 interval_type count = get_period_count();
00520
00521 #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
00522 if(count < STLSOFT_GEN_SINT64_SUFFIX(0x8637BD05AF6))
00523 #else
00524 if(count < interval_type(0x863, 0x7BD05AF6))
00525 #endif
00526 {
00527 result = (count * interval_type(1000000)) / frequency_();
00528 }
00529 else
00530 {
00531 result = (count / frequency_()) * interval_type(1000000);
00532 }
00533
00534 return result;
00535 }
00536
00537
00538 inline performance_counter::interval_type performance_counter::stop_get_period_count_and_restart()
00539 {
00540 stop();
00541
00542 interval_type interval = get_period_count();
00543
00544 m_start = m_end;
00545
00546 return interval;
00547 }
00548
00549 inline performance_counter::interval_type performance_counter::stop_get_seconds_and_restart()
00550 {
00551 stop();
00552
00553 interval_type interval = get_seconds();
00554
00555 m_start = m_end;
00556
00557 return interval;
00558 }
00559
00560 inline performance_counter::interval_type performance_counter::stop_get_milliseconds_and_restart()
00561 {
00562 stop();
00563
00564 interval_type interval = get_milliseconds();
00565
00566 m_start = m_end;
00567
00568 return interval;
00569 }
00570
00571 inline performance_counter::interval_type performance_counter::stop_get_microseconds_and_restart()
00572 {
00573 stop();
00574
00575 interval_type interval = get_microseconds();
00576
00577 m_start = m_end;
00578
00579 return interval;
00580 }
00581
00582 #endif
00583
00584
00585
00586 #ifndef _WINSTL_NO_NAMESPACE
00587 # if defined(_STLSOFT_NO_NAMESPACE) || \
00588 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00589 }
00590 # else
00591 }
00592 }
00593 # endif
00594 #endif
00595
00596
00597
00598 #endif
00599
00600