2 * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "benchmark/MemoryPoller.h"
18 #include "benchmark/Types.h"
19 #include "benchmark/MemoryInfo.h"
29 MemoryPoller::MemoryPoller(std::chrono::milliseconds duration, bool gpu_poll)
30 : _duration(duration), _run(false), _term(false), _gpu_poll(gpu_poll)
32 if (prepareMemoryPolling() == false)
33 throw std::runtime_error("failed to prepare memory pooling");
35 _thread = std::thread{&MemoryPoller::process, this};
38 bool MemoryPoller::start(PhaseEnum phase)
40 if (std::find(_phases.begin(), _phases.end(), phase) != _phases.end())
42 std::cerr << getPhaseString(phase) << " is already processing/processed..." << std::endl;
47 std::lock_guard<std::mutex> lock(_mutex);
48 _phases.emplace_back(phase);
55 _cond_var_started.notify_all();
59 bool MemoryPoller::end(PhaseEnum phase)
61 if (std::find(_phases.begin(), _phases.end(), phase) == _phases.end())
63 std::cerr << getPhaseString(phase) << " is not started..." << std::endl;
70 std::lock_guard<std::mutex> lock(_mutex);
71 _phases.remove(phase);
72 stop = (_phases.size() == 0);
78 mem += getGpuMemory(_process_name);
80 if (mem > _rss_map[phase])
81 _rss_map[phase] = mem;
86 mem += getGpuMemory(_process_name);
88 _hwm_map[phase] = mem;
91 if (mem > _pss_map[phase])
92 _pss_map[phase] = mem;
97 _cond_var_started.notify_all();
103 void MemoryPoller::process()
105 std::unique_lock<std::mutex> lock_started(_mutex_started);
108 _cond_var_started.wait(lock_started, [&]() { return _run || _term; });
112 std::unique_lock<std::mutex> lock(_mutex);
114 uint32_t cur_rss = getVmRSS();
115 uint32_t cur_hwm = getVmHWM();
118 auto gpu_mem = getGpuMemory(_process_name);
122 uint32_t cur_pss = getPssSum();
124 for (auto &phase : _phases)
126 auto &rss = _rss_map.at(phase);
129 // hwm is gradually increasing
130 auto &hwm = _hwm_map.at(phase);
132 auto &pss = _pss_map.at(phase);
139 std::this_thread::sleep_for(std::chrono::milliseconds(_duration));
143 bool MemoryPoller::prepareMemoryPolling()
148 std::cerr << "failed to prepare parsing vmrss" << std::endl;
152 // (Additionally) GpuMemory
155 if (!prepareGpuMemory())
157 std::cerr << "failed to prepare parsing gpu memory" << std::endl;
161 // Needs process name
162 _process_name = getProcessName();
166 if (!preparePssSum())
168 std::cerr << "failed to prepare parsing pss sum" << std::endl;
175 } // namespace benchmark