• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 Google LLC.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #if defined(SPIRV_TIMER_ENABLED)
16 
17 #include "source/util/timer.h"
18 
19 #include <sys/resource.h>
20 #include <sys/time.h>
21 #include <iomanip>
22 #include <iostream>
23 #include <string>
24 
25 namespace spvtools {
26 namespace utils {
27 
PrintTimerDescription(std::ostream * out,bool measure_mem_usage)28 void PrintTimerDescription(std::ostream* out, bool measure_mem_usage) {
29   if (out) {
30     *out << std::setw(30) << "PASS name" << std::setw(12) << "CPU time"
31          << std::setw(12) << "WALL time" << std::setw(12) << "USR time"
32          << std::setw(12) << "SYS time";
33     if (measure_mem_usage) {
34       *out << std::setw(12) << "RSS delta" << std::setw(16) << "PGFault delta";
35     }
36     *out << std::endl;
37   }
38 }
39 
40 // Do not change the order of invoking system calls. We want to make CPU/Wall
41 // time correct as much as possible. Calling functions to get CPU/Wall time must
42 // closely surround the target code of measuring.
Start()43 void Timer::Start() {
44   if (report_stream_) {
45     if (getrusage(RUSAGE_SELF, &usage_before_) == -1)
46       usage_status_ |= kGetrusageFailed;
47     if (clock_gettime(CLOCK_MONOTONIC, &wall_before_) == -1)
48       usage_status_ |= kClockGettimeWalltimeFailed;
49     if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_before_) == -1)
50       usage_status_ |= kClockGettimeCPUtimeFailed;
51   }
52 }
53 
54 // The order of invoking system calls is important with the same reason as
55 // Timer::Start().
Stop()56 void Timer::Stop() {
57   if (report_stream_ && usage_status_ == kSucceeded) {
58     if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cpu_after_) == -1)
59       usage_status_ |= kClockGettimeCPUtimeFailed;
60     if (clock_gettime(CLOCK_MONOTONIC, &wall_after_) == -1)
61       usage_status_ |= kClockGettimeWalltimeFailed;
62     if (getrusage(RUSAGE_SELF, &usage_after_) == -1)
63       usage_status_ = kGetrusageFailed;
64   }
65 }
66 
Report(const char * tag)67 void Timer::Report(const char* tag) {
68   if (!report_stream_) return;
69 
70   report_stream_->precision(2);
71   *report_stream_ << std::fixed << std::setw(30) << tag;
72 
73   if (usage_status_ & kClockGettimeCPUtimeFailed)
74     *report_stream_ << std::setw(12) << "Failed";
75   else
76     *report_stream_ << std::setw(12) << CPUTime();
77 
78   if (usage_status_ & kClockGettimeWalltimeFailed)
79     *report_stream_ << std::setw(12) << "Failed";
80   else
81     *report_stream_ << std::setw(12) << WallTime();
82 
83   if (usage_status_ & kGetrusageFailed) {
84     *report_stream_ << std::setw(12) << "Failed" << std::setw(12) << "Failed";
85     if (measure_mem_usage_) {
86       *report_stream_ << std::setw(12) << "Failed" << std::setw(12) << "Failed";
87     }
88   } else {
89     *report_stream_ << std::setw(12) << UserTime() << std::setw(12)
90                     << SystemTime();
91     if (measure_mem_usage_) {
92       *report_stream_ << std::fixed << std::setw(12) << RSS() << std::setw(16)
93                       << PageFault();
94     }
95   }
96   *report_stream_ << std::endl;
97 }
98 
99 }  // namespace utils
100 }  // namespace spvtools
101 
102 #endif  // defined(SPIRV_TIMER_ENABLED)
103