00001 //===================================================== 00002 // File : portable_perf_analyzer.hh 00003 // Author : L. Plagne <laurent.plagne@edf.fr)> 00004 // Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002 00005 //===================================================== 00006 // 00007 // This program is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // This program is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 // 00020 #ifndef _PORTABLE_PERF_ANALYZER_HH 00021 #define _PORTABLE_PERF_ANALYZER_HH 00022 00023 #include "utilities.h" 00024 #include "timers/portable_timer.hh" 00025 00026 template <class Action> 00027 class Portable_Perf_Analyzer{ 00028 public: 00029 Portable_Perf_Analyzer( void ):_nb_calc(1),_nb_init(1),_chronos(){ 00030 MESSAGE("Portable_Perf_Analyzer Ctor"); 00031 }; 00032 Portable_Perf_Analyzer( const Portable_Perf_Analyzer & ){ 00033 INFOS("Copy Ctor not implemented"); 00034 exit(0); 00035 }; 00036 ~Portable_Perf_Analyzer( void ){ 00037 MESSAGE("Portable_Perf_Analyzer Dtor"); 00038 }; 00039 00040 00041 00042 inline double eval_mflops(int size) 00043 { 00044 00045 Action action(size); 00046 00047 // double time_baseline = time_init(action); 00048 // while (time_baseline < MIN_TIME_INIT) 00049 // { 00050 // _nb_init *= 2; 00051 // time_baseline = time_init(action); 00052 // } 00053 // 00054 // // optimize 00055 // for (int i=1; i<NB_TRIES; ++i) 00056 // time_baseline = std::min(time_baseline, time_init(action)); 00057 // 00058 // time_baseline = time_baseline/(double(_nb_init)); 00059 00060 double time_action = time_calculate(action); 00061 while (time_action < MIN_TIME) 00062 { 00063 _nb_calc *= 2; 00064 time_action = time_calculate(action); 00065 } 00066 00067 // optimize 00068 for (int i=1; i<NB_TRIES; ++i) 00069 time_action = std::min(time_action, time_calculate(action)); 00070 00071 // INFOS("size="<<size); 00072 // INFOS("_nb_init="<<_nb_init); 00073 // INFOS("_nb_calc="<<_nb_calc); 00074 00075 time_action = time_action / (double(_nb_calc)); 00076 00077 action.check_result(); 00078 00079 00080 double time_baseline = time_init(action); 00081 for (int i=1; i<NB_TRIES; ++i) 00082 time_baseline = std::min(time_baseline, time_init(action)); 00083 time_baseline = time_baseline/(double(_nb_init)); 00084 00085 00086 00087 // INFOS("time_baseline="<<time_baseline); 00088 // INFOS("time_action="<<time_action); 00089 00090 time_action = time_action - time_baseline; 00091 00092 // INFOS("time_corrected="<<time_action); 00093 00094 return action.nb_op_base()/(time_action*1000000.0); 00095 } 00096 00097 inline double time_init(Action & action) 00098 { 00099 // time measurement 00100 _chronos.start(); 00101 for (int ii=0; ii<_nb_init; ii++) 00102 action.initialize(); 00103 _chronos.stop(); 00104 return _chronos.user_time(); 00105 } 00106 00107 00108 inline double time_calculate(Action & action) 00109 { 00110 // time measurement 00111 _chronos.start(); 00112 for (int ii=0;ii<_nb_calc;ii++) 00113 { 00114 action.initialize(); 00115 action.calculate(); 00116 } 00117 _chronos.stop(); 00118 return _chronos.user_time(); 00119 } 00120 00121 unsigned long long get_nb_calc( void ) 00122 { 00123 return _nb_calc; 00124 } 00125 00126 00127 private: 00128 unsigned long long _nb_calc; 00129 unsigned long long _nb_init; 00130 Portable_Timer _chronos; 00131 00132 }; 00133 00134 #endif //_PORTABLE_PERF_ANALYZER_HH