Coverage Report

Created: 2026-04-09 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Simd/src/Simd/SimdPerformance.h
Line
Count
Source
1
/*
2
* Simd Library (http://ermig1979.github.io/Simd).
3
*
4
* Copyright (c) 2011-2021 Yermalayeu Ihar.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to deal
8
* in the Software without restriction, including without limitation the rights
9
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
* copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
12
*
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
* SOFTWARE.
23
*/
24
#ifndef __SimdPerformance_h__
25
#define __SimdPerformance_h__
26
27
#include "Simd/SimdDefs.h"
28
29
#include <string>
30
#include <sstream>
31
32
namespace Simd
33
{
34
    typedef std::string String;
35
36
    template <class T> SIMD_INLINE String ToStr(const T & value)
37
0
    {
38
0
        std::stringstream ss;
39
0
        ss << value;
40
0
        return ss.str();
41
0
    }
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Simd::ToStr<int>(int const&)
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Simd::ToStr<unsigned long>(unsigned long const&)
42
}
43
44
#if defined(SIMD_PERFORMANCE_STATISTIC) && (defined(NDEBUG) || defined(SIMD_PERF_STAT_IN_DEBUG))
45
46
#include "Simd/SimdTime.h"
47
48
#include <limits>
49
#include <iostream>
50
#include <iomanip>
51
#include <memory>
52
#include <map>
53
#include <thread>
54
#include <mutex>
55
#include <algorithm>
56
57
namespace Simd
58
{
59
    namespace Base
60
    {
61
        class PerformanceMeasurer
62
        {
63
            String  _name;
64
            int64_t _start, _current, _total, _min, _max;
65
            int64_t _count, _flop;
66
            bool _entered, _paused;
67
68
        public:
69
            PerformanceMeasurer(const String& name = "Unknown", int64_t flop = 0);
70
71
            PerformanceMeasurer(const PerformanceMeasurer& pm);
72
73
            void Enter();
74
75
            void Leave(bool pause = false);
76
77
            String Statistic() const;
78
79
            void Combine(const PerformanceMeasurer& other);
80
81
        private:
82
            double Average() const;
83
            double GFlops() const;
84
        };
85
86
        class PerformanceMeasurerHolder
87
        {
88
            PerformanceMeasurer * _pm;
89
90
        public:
91
            SIMD_INLINE PerformanceMeasurerHolder(PerformanceMeasurer * pm, bool enter = true)
92
                : _pm(pm)
93
            {
94
                if (_pm && enter)
95
                    _pm->Enter();
96
            }
97
98
            SIMD_INLINE void Enter()
99
            {
100
                if (_pm)
101
                    _pm->Enter();
102
            }
103
104
            SIMD_INLINE void Leave(bool pause)
105
            {
106
                if (_pm)
107
                    _pm->Leave(pause);
108
            }
109
110
            SIMD_INLINE ~PerformanceMeasurerHolder()
111
            {
112
                if (_pm)
113
                    _pm->Leave();
114
            }
115
        };
116
117
        class PerformanceMeasurerStorage
118
        {
119
            typedef PerformanceMeasurer Pm;
120
            typedef std::shared_ptr<Pm> PmPtr;
121
            typedef std::map<String, PmPtr> FunctionMap;
122
            typedef std::map<std::thread::id, FunctionMap> ThreadMap;
123
124
            ThreadMap _map;
125
            mutable std::mutex _mutex;
126
            String _report;
127
128
            SIMD_INLINE FunctionMap & ThisThread()
129
            {
130
                static thread_local FunctionMap * thread = NULL;
131
                if (thread == NULL)
132
                {
133
                    std::lock_guard<std::mutex> lock(_mutex);
134
                    thread = &_map[std::this_thread::get_id()];
135
                }
136
                return *thread;
137
            }
138
139
        public:
140
            static PerformanceMeasurerStorage s_storage;
141
142
            PerformanceMeasurerStorage()
143
            {
144
            }
145
146
            SIMD_INLINE PerformanceMeasurer * Get(const String & name, int64_t flop = 0)
147
            {
148
                FunctionMap & thread = ThisThread();
149
                PerformanceMeasurer * pm = NULL;
150
                FunctionMap::iterator it = thread.find(name);
151
                if (it == thread.end())
152
                {
153
                    pm = new PerformanceMeasurer(name, flop);
154
                    thread[name].reset(pm);
155
                }
156
                else
157
                    pm = it->second.get();
158
                return pm;
159
            }
160
161
            SIMD_INLINE PerformanceMeasurer * Get(const String func, const String & desc, int64_t flop = 0)
162
            {
163
                return Get(func + "{ " + desc + " }", flop);
164
            }
165
166
            const char* PerformanceStatistic();
167
        };
168
    }
169
}
170
#define SIMD_PERF_FUNCF(flop) Simd::Base::PerformanceMeasurerHolder SIMD_CAT(__pmh, __LINE__)(Simd::Base::PerformanceMeasurerStorage::s_storage.Get(SIMD_FUNCTION, (int64_t)(flop)))
171
#define SIMD_PERF_FUNC() SIMD_PERF_FUNCF(0)
172
#define SIMD_PERF_BEGF(desc, flop) Simd::Base::PerformanceMeasurerHolder SIMD_CAT(__pmh, __LINE__)(Simd::Base::PerformanceMeasurerStorage::s_storage.Get(SIMD_FUNCTION, desc, (int64_t)(flop)))
173
#define SIMD_PERF_BEG(desc) SIMD_PERF_BEGF(desc, 0)
174
#define SIMD_PERF_IFF(cond, desc, flop) Simd::Base::PerformanceMeasurerHolder SIMD_CAT(__pmh, __LINE__)((cond) ? Simd::Base::PerformanceMeasurerStorage::s_storage.Get(SIMD_FUNCTION, desc, (int64_t)(flop)) : NULL)
175
#define SIMD_PERF_IF(cond, desc) SIMD_PERF_IFF(cond, desc, 0)
176
#define SIMD_PERF_END(desc) Simd::Base::PerformanceMeasurerStorage::s_storage.Get(SIMD_FUNCTION, desc)->Leave();
177
#define SIMD_PERF_INITF(name, desc, flop) Simd::Base::PerformanceMeasurerHolder name(Simd::Base::PerformanceMeasurerStorage::s_storage.Get(SIMD_FUNCTION, desc, (int64_t)(flop)), false);
178
#define SIMD_PERF_INIT(name, desc)  SIMD_PERF_INITF(name, desc, 0);
179
#define SIMD_PERF_START(name) name.Enter(); 
180
#define SIMD_PERF_PAUSE(name) name.Leave(true);
181
#define SIMD_PERF_EXT(ext) Simd::Base::PerformanceMeasurerHolder SIMD_CAT(__pmh, __LINE__)((ext)->Perf(SIMD_FUNCTION)) 
182
#else//SIMD_PERFORMANCE_STATISTIC
183
#define SIMD_PERF_FUNCF(flop)
184
#define SIMD_PERF_FUNC()
185
#define SIMD_PERF_BEGF(desc, flop)
186
#define SIMD_PERF_BEG(desc)
187
#define SIMD_PERF_IFF(cond, desc, flop)
188
#define SIMD_PERF_IF(cond, desc)
189
#define SIMD_PERF_END(desc)
190
#define SIMD_PERF_INITF(name, desc, flop)
191
#define SIMD_PERF_INIT(name, desc)
192
#define SIMD_PERF_START(name)
193
#define SIMD_PERF_PAUSE(name)
194
#define SIMD_PERF_EXT(ext)
195
#endif//SIMD_PERFORMANCE_STATISTIC 
196
197
#endif//__SimdPerformance_h__