Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:29:19

0001 #ifndef FWCore_Utilities_HRRealTime_H
0002 #define FWCore_Utilities_HRRealTime_H
0003 /*  
0004  *  High Resolution Real Timer
0005  *  inline high-resolution real timer
0006  *  to be used for precise measurements of performance of
0007  *  "small" chunks of code.  
0008  *
0009  *  returns time in "nominal" cpu-clock unit
0010  *  on most recent hw-architecure it is compensated for clock-rate variations
0011  *  so to get seconds it shall be multiplied for a nominal cpu-clock unit
0012  *  Performance comparison make sense only if the clock-rate has been fixed
0013  */
0014 
0015 namespace edm {
0016   namespace details {
0017 
0018     //
0019     //  defines "rdtsc"
0020     //
0021 #if defined(__i386__)
0022 
0023     static __inline__ unsigned long long rdtsc(void) {
0024       unsigned long long int x;
0025       __asm__ volatile(".byte 0x0f, 0x31" : "=A"(x));
0026       return x;
0027     }
0028 #elif defined(__x86_64__)
0029 
0030     static __inline__ unsigned long long rdtsc(void) {
0031       unsigned hi, lo;
0032       __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
0033       return ((unsigned long long)lo) | (((unsigned long long)hi) << 32);
0034     }
0035 
0036 #elif defined(__powerpc__)
0037 
0038     static __inline__ unsigned long long rdtsc(void) {
0039       unsigned long long int result = 0;
0040       unsigned long int upper, lower, tmp;
0041       __asm__ volatile(
0042           "0:                  \n"
0043           "\tmftbu   %0           \n"
0044           "\tmftb    %1           \n"
0045           "\tmftbu   %2           \n"
0046           "\tcmpw    %2,%0        \n"
0047           "\tbne     0b         \n"
0048           : "=r"(upper), "=r"(lower), "=r"(tmp));
0049       result = upper;
0050       result = result << 32;
0051       result = result | lower;
0052 
0053       return (result);
0054     }
0055 #elif defined(__arm__)
0056 #warning unsigned long long rdtsc(void) is not implemented on ARMv7 architecture. Returning 0 by default.
0057     static __inline__ unsigned long long rdtsc(void) { return 0; }
0058 #elif defined(__aarch64__)
0059     static __inline__ unsigned long long rdtsc(void) {
0060       // We will be reading CNTVCT_EL0 (the virtual counter), which is prepared for us by OS.
0061       // The system counter sits outside multiprocessor in SOC and runs on a different frequency.
0062       // Increments at a fixed frequency, typically in the range 1-50MHz.
0063       // Applications can figure out system counter configuration via CNTFRQ_EL0.
0064       //
0065       // Notice:
0066       // Reads of CNTVCT_EL0 can occur speculatively and out of order relative to other
0067       // instructions executed on the same PE.
0068       // For example, if a read from memory is used to obtain a signal from another agent
0069       // that indicates that CNTVCT_EL0 must be read, an ISB is used to ensure that the
0070       // read of CNTVCT_EL0 occurs after the signal has been read from memory
0071       //
0072       // More details:
0073       // Chapter D6: The Generic Timer in AArch64 state
0074       // ARM DDI 0487B.a, ID033117 (file: DDI0487B_a_armv8_arm.pdf)
0075       unsigned long long ret;  // unsigned 64-bit value
0076       __asm__ __volatile__("isb; mrs %0, cntvct_el0" : "=r"(ret));
0077       return ret;
0078     }
0079 #else
0080 #error The file FWCore/Utilities/interface/HRRealTime.h needs to be set up for your CPU type.
0081 #endif
0082   }  // namespace details
0083 }  // namespace edm
0084 
0085 namespace edm {
0086 
0087   typedef long long int HRTimeDiffType;
0088   typedef unsigned long long int HRTimeType;
0089 
0090   // High Precision real time in clock-units
0091   inline HRTimeType hrRealTime() { return details::rdtsc(); }
0092 
0093 }  // namespace edm
0094 
0095 #endif  //   FWCore_Utilities__HRRealTime_H