CTime.cpp
Go to the documentation of this file.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 #include <sofa/helper/system/thread/CTime.h>
00028
00029 #ifdef WIN32
00030 # include <windows.h>
00031 # if _MSC_VER >= 1400
00032 # include <intrin.h>
00033 # endif
00034 #else
00035 # include <unistd.h>
00036 # include <sys/time.h>
00037 #endif
00038 #if defined(__ia64__) && (defined(__EDG_VERSION) || defined(__ECC))
00039 #include <ia64intrin.h>
00040 #endif
00041 #include <iostream>
00042
00043
00044
00045
00046
00047
00048 namespace sofa
00049 {
00050
00051 namespace helper
00052 {
00053
00054 namespace system
00055 {
00056
00057 namespace thread
00058 {
00059
00060 #ifdef WIN32
00061
00062 ctime_t CTime::getRefTime()
00063 {
00064 LARGE_INTEGER a;
00065 QueryPerformanceCounter(&a);
00066 return(a.QuadPart);
00067 }
00068
00069 ctime_t CTime::getRefTicksPerSec()
00070 {
00071 LARGE_INTEGER b;
00072 QueryPerformanceFrequency(&b);
00073 return(b.QuadPart);
00074 }
00075
00076 void CTime::sleep(double a)
00077 {
00078 _sleep((long)(a*1000.0));
00079 }
00080
00081 #else
00082
00083 ctime_t CTime::getRefTime()
00084 {
00085 struct timeval tv;
00086 gettimeofday(&tv,0);
00087 return ((ctime_t)tv.tv_sec)*1000000 + ((ctime_t)tv.tv_usec);
00088 }
00089
00090 ctime_t CTime::getRefTicksPerSec()
00091 {
00092 return (ctime_t)1000000;
00093 }
00094
00095 void CTime::sleep(double a)
00096 {
00097 usleep((unsigned int)(a*1000000.0));
00098 }
00099
00100 #endif
00101
00102
00103
00104 #ifdef SOFA_RDTSC
00105 #if defined(_MSC_VER)
00106 ctime_t CTime::getFastTime()
00107 {
00108 #if _MSC_VER >= 1400
00109 return __rdtsc();
00110 #else
00111 _asm _emit 0x0F
00112 _asm _emit 0x31
00113 #endif
00114 }
00115 #elif defined(__ia64__)
00116 # if defined(__EDG_VERSION) || defined(__ECC)
00117 ctime_t CTime::getFastTime()
00118 {
00119 return __getReg(_IA64_REG_AR_ITC);
00120 }
00121 # else
00122 ctime_t CTime::getFastTime()
00123 {
00124 ctime_t t;
00125 __asm__ __volatile__("mov %0=ar.itc" : "=r"(t) :: "memory");
00126 return t;
00127 }
00128 # endif
00129 #elif defined(__powerpc__) || defined(__POWERPC__)
00130 ctime_t CTime::getFastTime()
00131 {
00132 register unsigned long t_u;
00133 register unsigned long t_l;
00134 asm volatile ("mftbu %0" : "=r" (t_u) );
00135 asm volatile ("mftb %0" : "=r" (t_l) );
00136 return (((ctime_t)t_u)<<32UL) | t_l;
00137 }
00138 #elif defined(__GNUC__)
00139 ctime_t CTime::getFastTime()
00140 {
00141 ctime_t t;
00142 __asm__ volatile ("rdtsc" : "=A" (t) );
00143 return t;
00144 }
00145 #else
00146 #error RDTSC not supported on this platform
00147 #endif
00148
00149 ctime_t CTime::computeTicksPerSec()
00150 {
00151 ctime_t tick1,tick2,tick3,tick4, time1,time2;
00152 ctime_t reffreq = getRefTicksPerSec();
00153
00154 tick1 = getFastTime();
00155 time1 = getRefTime();
00156 tick2 = getFastTime();
00157
00158 sleep(0.1);
00159
00160 tick3 = getFastTime();
00161 time2 = getRefTime();
00162 tick4 = getFastTime();
00163
00164 double cpu_frequency_min =(tick3-tick2) * ((double)reffreq) / (time2 - time1);
00165 double cpu_frequency_max =(tick4-tick1) * ((double)reffreq) / (time2 - time1);
00166 std::cout << " CPU Frequency in [" << ((int)(cpu_frequency_min/1000000))*0.001 << " .. " << ((ctime_t)(cpu_frequency_max/1000000))*0.001 << "] GHz" << std::endl;
00167 return (ctime_t)((cpu_frequency_min + cpu_frequency_max)/2);
00168 }
00169
00170 ctime_t CTime::getTicksPerSec()
00171 {
00172 static const ctime_t freq = computeTicksPerSec();
00173 return freq;
00174 }
00175
00176 #else
00177
00178 ctime_t CTime::getFastTime()
00179 {
00180 return getRefTime();
00181 }
00182
00183 ctime_t CTime::getTicksPerSec()
00184 {
00185 return getRefTicksPerSec();
00186 }
00187
00188 #endif
00189
00190 ctime_t CTime::getTime()
00191 {
00192 static ctime_t last = 0;
00193 ctime_t t = getFastTime();
00194 if (t <= last)
00195 t = last;
00196 else
00197 last = t;
00198 return t;
00199 }
00200
00201 }
00202
00203 }
00204
00205 }
00206
00207 }
00208