xref: /aosp_15_r20/external/intel-media-driver/cmrtlib/agnostic/hardware/cm_perf_statistics.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 #include "cm_perf_statistics.h"
23 #include "cm_mem.h"
24 #include "cm_sdk_provider.h"
25 
26 #if MDF_PROFILER_ENABLED
27 
CmPerfStatistics()28 CmPerfStatistics::CmPerfStatistics()
29 {
30 
31     m_apiCallRecordCount  = 0;
32     m_apiCallFile         = nullptr;
33 
34     m_perfStatisticFile   = nullptr;
35     m_perfStatisticCount = 0;
36 
37     m_profilerOn      = false;
38     m_profilerLevel    = CM_RT_PERF_LOG_LEVEL_DEFAULT;
39 
40     GetProfilerLevel(); // get profiler level from env variable "CM_RT_PERF_LOG"
41 
42     if(m_profilerLevel >= CM_RT_PERF_LOG_LEVEL_ETW)
43     {   // Register 'MDF Provider' in System
44         EventRegisterMDF_PROVIDER();
45     }
46 
47 }
48 
~CmPerfStatistics()49 CmPerfStatistics::~CmPerfStatistics()
50 {
51     DumpApiCallRecords();
52 
53     DumpPerfStatisticRecords();
54 }
55 
GetProfilerLevel()56 void CmPerfStatistics::GetProfilerLevel()
57 {   // Enabled Profiler in Debug Mode
58     m_profilerLevel = CM_RT_PERF_LOG_LEVEL_RECORDS;
59     m_profilerOn   = true;
60     return;
61 }
62 
63 //! Insert API Call Records Into m_apiCallRecords Array and Update Perf Statistic Array accordingly
InsertApiCallRecord(char * functionName,float time,LARGE_INTEGER start,LARGE_INTEGER end)64 void CmPerfStatistics::InsertApiCallRecord(char *functionName, float time, LARGE_INTEGER start, LARGE_INTEGER end)
65 {
66     CLock locker(m_criticalSectionOnApiCallRecords);
67 
68     ApiCallRecord *records = new ApiCallRecord ;
69 
70     records->startTime = start;
71     records->endTime   = end;
72     records->duration   = time;
73 
74     CM_STRCPY(records->functionName, MSG_STRING_SIZE, functionName);
75 
76     m_apiCallRecords.push_back(records);
77     m_apiCallRecordCount++;
78 
79     InsertPerfStatistic(records);
80 
81 }
82 
83 //Update Perf Statistic Array
InsertPerfStatistic(ApiCallRecord * record)84 void CmPerfStatistics::InsertPerfStatistic(ApiCallRecord *record)
85 {
86     uint32_t index = 0;
87 
88     for( index = 0 ; index < m_perfStatisticCount ; index ++)
89     {
90         ApiPerfStatistic *perfStatisticRecords = m_perfStatisticRecords[index];
91         if(perfStatisticRecords != nullptr)
92         {
93             if(!strcmp(record->functionName, perfStatisticRecords->functionName))
94             { // existing
95                perfStatisticRecords->callTimes ++ ;
96                perfStatisticRecords->time += record->duration;
97 
98                //Update statistic records
99                m_perfStatisticRecords[index] = perfStatisticRecords;
100 
101                break;
102             }
103         }
104     }
105 
106     if(index == m_perfStatisticCount)
107     { // record does not exist, create new entry
108         ApiPerfStatistic *perfStatisticRecords = new ApiPerfStatistic;
109         CM_STRCPY(perfStatisticRecords->functionName, MSG_STRING_SIZE, record->functionName);
110 
111         perfStatisticRecords->callTimes = 1;
112         perfStatisticRecords->time       = record->duration;
113 
114         m_perfStatisticRecords.push_back(perfStatisticRecords);
115         m_perfStatisticCount ++;
116     }
117 
118     return ;
119 }
120 
121 //Dump APICall Records and Release m_apiCallRecords Array
DumpApiCallRecords()122 void CmPerfStatistics::DumpApiCallRecords()
123 {
124     if(!m_profilerOn)
125     {
126         return ;
127     }
128 
129     CM_FOPEN(m_apiCallFile, "CmPerfLog.csv", "wb");
130     if(! m_apiCallFile )
131     {
132         fprintf(stdout, "Fail to create file CmPerfLog.csv \n ");
133         return ;
134     }
135     fprintf(m_apiCallFile,  "%-40s %s \t %s \t %s \n", "FunctionName", "StartTime", "EndTime", "Duration");
136 
137     for(uint32_t i=0 ; i< m_apiCallRecordCount ; i++)
138     {
139         ApiCallRecord *records = m_apiCallRecords[i];
140 
141         fprintf(m_apiCallFile,  "%-40s  %lld \t %lld \t %fms \n", records->functionName,
142            records->startTime.QuadPart, records->endTime.QuadPart, records->duration);
143 
144         CmSafeRelease(records);
145     }
146 
147     m_apiCallRecords.clear();
148 
149     fclose(m_apiCallFile);
150 
151 }
152 
153 //Dump Perf Statistic Records and Release m_perfStatisticRecords Array
DumpPerfStatisticRecords()154 void CmPerfStatistics::DumpPerfStatisticRecords()
155 {
156     if(!m_profilerOn)
157     {
158         return ;
159     }
160 
161     CM_FOPEN(m_perfStatisticFile, "CmPerfStatistics.txt","wb");
162     if(!m_perfStatisticFile )
163     {
164         fprintf(stdout, "Fail to create file CmPerfStatistics.txt \n ");
165         return ;
166     }
167     fprintf(m_perfStatisticFile,  "%-40s %s \t %s \n", "FunctionName", "Total Time(ms)", "Called Times");
168 
169     for(uint32_t i=0 ; i< m_perfStatisticCount; i++)
170     {
171         ApiPerfStatistic *perfStatisticRecords = m_perfStatisticRecords[i];
172 
173         fprintf(m_perfStatisticFile,  "%-40s %fms \t %d \n", perfStatisticRecords->functionName,
174            perfStatisticRecords->time, perfStatisticRecords->callTimes);
175 
176         CmSafeRelease(perfStatisticRecords);
177     }
178 
179     m_perfStatisticRecords.clear();
180 
181     fclose(m_perfStatisticFile);
182 
183 }
184 
185 #endif
186