| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- #include <chrono>
- #include <thread>
- #include <vector>
- #include <iostream>
- #include <condition_variable>
- #include <cstdlib>
- #include <math.h>
- #include <type_traits>
- #include <unistd.h>
- #include <sys/syscall.h>
- #include <sys/time.h>
- static inline uint64_t getCurrentTime()
- {
- #if defined(__i386__)
- int64_t ret;
- __asm__ volatile("rdtsc" : "=A"(ret));
- return ret;
- #elif defined(__x86_64__) || defined(__amd64__)
- uint64_t low, high;
- __asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
- return (high << 32) | low;
- #endif
- }
- int OBJECTS = 500;
- #define STR(x) #x
- int64_t calculate_cpu_frequency()//per sec
- {
- double g_TicksPerNanoSec;
- struct timespec begints, endts;
- uint64_t begin = 0, end = 0;
- clock_gettime(CLOCK_MONOTONIC, &begints);
- begin = getCurrentTime();
- volatile uint64_t i;
- for (i = 0; i < 100000000; i++); /* must be CPU intensive */
- end = getCurrentTime();
- clock_gettime(CLOCK_MONOTONIC, &endts);
- struct timespec tmpts;
- const int NANO_SECONDS_IN_SEC = 1000000000;
- tmpts.tv_sec = endts.tv_sec - begints.tv_sec;
- tmpts.tv_nsec = endts.tv_nsec - begints.tv_nsec;
- if (tmpts.tv_nsec < 0)
- {
- tmpts.tv_sec--;
- tmpts.tv_nsec += NANO_SECONDS_IN_SEC;
- }
- uint64_t nsecElapsed = tmpts.tv_sec * 1000000000LL + tmpts.tv_nsec;
- g_TicksPerNanoSec = (double)(end - begin) / (double)nsecElapsed;
- int64_t cpu_frequency = int(g_TicksPerNanoSec * 1000);
- return cpu_frequency;
- }
- const auto CPU_FREQUENCY = calculate_cpu_frequency();
- # define TICKS_TO_US(ticks) ticks / CPU_FREQUENCY
- void localSleep(int magic=200000)
- {
- volatile int i = 0;
- for (; i < magic; ++i);
- }
- template<class Clock>
- auto calcDelta(int magic=200000) -> decltype(Clock::now().time_since_epoch().count())
- {
- auto start = Clock::now().time_since_epoch().count();
- localSleep(magic);
- auto end = Clock::now().time_since_epoch().count();
- return end - start;
- }
- template<class Clock>
- double calcDuration(int objects)
- {
- const auto frequency = Clock::period::den / Clock::period::num;
- auto start = Clock::now();
- decltype(Clock::now().time_since_epoch().count()) summ = 0;
- for (int i=0; i < objects; i++)
- {
- summ += calcDelta<Clock>();
- }
- summ = summ * 1000000LL / frequency;
- auto end = Clock::now();
- auto elapsed =
- std::chrono::duration_cast<std::chrono::microseconds>(end - start);
- return (elapsed.count()-summ)/double(objects)/2.0;
- }
- uint64_t calcDeltaRdtsc(int magic=200000)
- {
- auto start = getCurrentTime();
- localSleep(magic);
- auto end = getCurrentTime();
- return end - start;
- }
- double calcDurationByRdtsc(int objects)
- {
- auto start = getCurrentTime();
- uint64_t summ = 0;
- for (int i=0; i < objects; i++)
- {
- summ += calcDeltaRdtsc();
- }
- auto end = getCurrentTime();
- return TICKS_TO_US((end - start - summ))/double(objects)/2.0;
- }
- uint64_t calcDeltaSysCall(int magic, int type)
- {
- timespec tp0,tp1;
- syscall(SYS_clock_gettime, type, &tp0);
- auto start = tp0.tv_sec*1000000000+tp0.tv_nsec;
- localSleep(magic);
- syscall(SYS_clock_gettime, type, &tp1);
- auto end = tp1.tv_sec*1000000000+tp1.tv_nsec;
- return end - start;
- }
- double calcDurationBySyscall(int objects, int type)
- {
- timespec tp0,tp1;
- syscall(SYS_clock_gettime, type, &tp0);
- auto start = tp0.tv_sec*1000000000+tp0.tv_nsec;
- uint64_t summ = 0;
- for (int i=0; i < objects; i++)
- {
- summ += calcDeltaSysCall(200000,type);
- }
- syscall(SYS_clock_gettime, type, &tp1);
- auto end = tp1.tv_sec*1000000000+tp1.tv_nsec;
- return (end - start - summ)/double(objects)/2.0/1000.0;
- }
- uint64_t calcDeltaSysGetTime(int magic, int type)
- {
- timespec tp0,tp1;
- clock_gettime(type, &tp0);
- auto start = tp0.tv_sec*1000000000+tp0.tv_nsec;
- localSleep(magic);
- clock_gettime(type, &tp1);
- auto end = tp1.tv_sec*1000000000+tp1.tv_nsec;
- return end - start;
- }
- double calcDurationByGetTime(int objects, int type)
- {
- timespec tp0,tp1;
- clock_gettime(type, &tp0);
- auto start = tp0.tv_sec*1000000000+tp0.tv_nsec;
- uint64_t summ = 0;
- for (int i=0; i < objects; i++)
- {
- summ += calcDeltaSysGetTime(200000,type);
- }
- clock_gettime(type, &tp1);
- auto end = tp1.tv_sec*1000000000+tp1.tv_nsec;
- return (end - start - summ)/double(objects)/2.0/1000.0;
- }
- uint64_t calcDeltaSysGetTimeOfDay(int magic=200000)
- {
- timeval tv0,tv1;
- gettimeofday(&tv0,0);
- auto start = tv0.tv_sec*1000000+tv0.tv_usec;
- localSleep(magic);
- gettimeofday(&tv1, 0);
- auto end = tv1.tv_sec*1000000+tv1.tv_usec;
- return end - start;
- }
- double calcDurationByGetTimeOfDay(int objects)
- {
- timeval tv0,tv1;
- gettimeofday(&tv0,0);
- auto start = tv0.tv_sec*1000000+tv0.tv_usec;
- uint64_t summ = 0;
- for (int i=0; i < objects; i++)
- {
- summ += calcDeltaSysGetTimeOfDay();
- }
- gettimeofday(&tv1, 0);
- auto end = tv1.tv_sec*1000000+tv1.tv_usec;
- return (end - start - summ)/double(objects)/2.0;
- }
- int main(int argc, char* argv[])
- {
- if (argc > 1 && argv[1]){
- OBJECTS = std::atoi(argv[1]);
- }
- std::cout << STR(std::chrono::steady_clock) << ": "<<calcDuration<std::chrono::steady_clock>(OBJECTS) << " usec\n";
- std::cout << STR(std::chrono::high_resolution_clock)<< ": " << calcDuration<std::chrono::high_resolution_clock>(OBJECTS) << " usec\n";
- std::cout << STR(std::chrono::system_clock)<< ": " << calcDuration<std::chrono::system_clock>(OBJECTS) << " usec\n";
- std::cout << "\n";
- std::cout << "rdtsc: " << calcDurationByRdtsc(OBJECTS) << " usec\n";
- std::cout << "\n";
- std::cout << "syscall(SYS_clock_gettime, CLOCK_MONOTONIC): " << calcDurationBySyscall(OBJECTS,CLOCK_MONOTONIC) << " usec\n";
- std::cout << "syscall(SYS_clock_gettime, CLOCK_REALTIME): " << calcDurationBySyscall(OBJECTS,CLOCK_REALTIME) << " usec\n";
- std::cout << "syscall(SYS_clock_gettime, CLOCK_MONOTONIC_RAW): " << calcDurationBySyscall(OBJECTS,CLOCK_MONOTONIC_RAW) << " usec\n";
- std::cout << "syscall(SYS_clock_gettime, CLOCK_MONOTONIC_COARSE): " << calcDurationBySyscall(OBJECTS,CLOCK_MONOTONIC_COARSE) << " usec\n";
- std::cout << "syscall(SYS_clock_gettime, CLOCK_REALTIME_COARSE): " << calcDurationBySyscall(OBJECTS,CLOCK_REALTIME_COARSE) << " usec\n";
- std::cout << "\n";
- std::cout << "clock_gettime(CLOCK_MONOTONIC): " << calcDurationByGetTime(OBJECTS,CLOCK_MONOTONIC) << " usec\n";
- std::cout << "clock_gettime(CLOCK_REALTIME): " << calcDurationByGetTime(OBJECTS,CLOCK_REALTIME) << " usec\n";
- std::cout << "clock_gettime(CLOCK_MONOTONIC_RAW): " << calcDurationByGetTime(OBJECTS,CLOCK_MONOTONIC_RAW) << " usec\n";
- std::cout << "clock_gettime(CLOCK_MONOTONIC_COARSE): " << calcDurationByGetTime(OBJECTS,CLOCK_MONOTONIC_COARSE) << " usec\n";
- std::cout << "clock_gettime(CLOCK_REALTIME_COARSE): " << calcDurationByGetTime(OBJECTS,CLOCK_REALTIME_COARSE) << " usec\n";
- std::cout << "\n";
- std::cout << "gettimeofday(): " << calcDurationByGetTimeOfDay(OBJECTS) << " usec\n";
- return 0;
- }
|