1/*******************************************************************************
2 Copyright (c) The Taichi Authors (2016- ). All Rights Reserved.
3 The use of this software is governed by the LICENSE file.
4*******************************************************************************/
5
6#pragma once
7
8#include <string>
9#include <cstdio>
10#include <map>
11#include "taichi/common/core.h"
12#if defined(TI_PLATFORM_UNIX)
13#include <sys/time.h>
14#else
15#pragma warning(push)
16#pragma warning(disable : 4005)
17#include "taichi/platform/windows/windows.h"
18#pragma warning(pop)
19#endif
20
21namespace taichi {
22
23#define TIME(x) \
24 { \
25 char timer_name[1000]; \
26 sprintf_s(timer_name, "%s[%d]: %s", __FILENAME__, __LINE__, #x); \
27 taichi::Time::Timer _(timer_name); \
28 x; \
29 }
30#define TI_TIME(x) TIME(x)
31
32#include <stdint.h>
33
34class TI_DLL_EXPORT Time {
35 public:
36 static double get_time();
37 static uint64 get_cycles();
38 static void wait_until(double t);
39
40 static void usleep(double us);
41 static void msleep(double ms);
42 static void sleep(double s);
43
44 class Timer {
45 static std::map<std::string, std::pair<double, int>> memo;
46
47 protected:
48 std::string name;
49 double start_time;
50
51 virtual double get_time();
52
53 virtual void print_record(const char *left, double elapsed, double average);
54
55 void output();
56
57 bool have_output;
58
59 public:
60 explicit Timer(std::string name);
61
62 Timer() {
63 }
64
65 virtual ~Timer() {
66 output();
67 }
68 };
69
70 class TickTimer : public Timer {
71 protected:
72 double get_time() override;
73
74 void print_record(const char *left,
75 double elapsed,
76 double average) override;
77
78 public:
79 explicit TickTimer(std::string name);
80
81 ~TickTimer() override {
82 output();
83 }
84 };
85
86 class FPSCounter {
87 public:
88 static void count(std::string name) {
89 if (last_refresh.find(name) == last_refresh.end()) {
90 last_refresh[name] = get_time();
91 counter[name] = 0;
92 }
93 counter[name]++;
94 double current_time = get_time();
95 if (current_time > 1 + last_refresh[name]) {
96 last_refresh[name] = last_refresh[name] + 1;
97 printf("FPS [%s]: %d\n", name.c_str(), counter[name]);
98 counter[name] = 0;
99 }
100 }
101
102 private:
103 static std::map<std::string, double> last_refresh;
104 static std::map<std::string, int> counter;
105 };
106};
107
108} // namespace taichi
109