Commit 189ec008 authored by Micha Mueller's avatar Micha Mueller
Browse files

Perf plugin: add support for single_counters in config files

parent 9aa3d09a
......@@ -16,6 +16,15 @@ template_group def2 {
mqttpart xx
}
template_single_counter def3 {
interval 2000
mqttpart xx
minValues 3
cpus 1-3
type PERF_TYPE_HARDWARE
config PERF_COUNT_HW_CACHE_REFERENCES
}
group hw_i {
default def1
mqttpart xx
......@@ -44,23 +53,19 @@ group hw_bm {
}
}
group cache {
interval 2000
mqttpart xx
single_counter cacheReferences {
default def3
cpus 2-3
mqttsuffix 10
}
single_counter cacheMisses {
interval 2000
mqttpart xxxx
minValues 3
cpus 2-3
counter references {
mqttsuffix 10
type PERF_TYPE_HARDWARE
config PERF_COUNT_HW_CACHE_REFERENCES
}
counter misses {
mqttsuffix 20
type PERF_TYPE_HARDWARE
config PERF_COUNT_HW_CACHE_MISSES
}
cpus 2-3
type PERF_TYPE_HARDWARE
config PERF_COUNT_HW_CACHE_MISSES
}
group sw {
......
......@@ -124,57 +124,88 @@ bool PerfeventConfigurator::readConfig(std::string cfgPath) {
auto ret = _templateSensorGroups.insert(std::pair<std::string, PerfSensorGroup*>(val.second.data(), group));
if(!ret.second) {
LOG(warning) << "Template " << _groupName << " " << val.second.data() << " already exists! Omitting...";
delete group;
}
} else {
LOG(warning) << "Template " << _groupName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
delete group;
}
}
//template single sensor
} else if (boost::iequals(val.first, "template_single_" + _baseName)) {
LOG(debug) << "Template single " << _baseName << " \"" << val.second.data() << "\"";
if (!val.second.empty()) {
PerfSensorGroup* group = new PerfSensorGroup(val.second.data());
if (readSensorGroup(*group, val.second)) {
//check if cpus-list is given for this template single counter
boost::optional<boost::property_tree::iptree&> cpus = val.second.get_child_optional("cpus");
if(cpus) {
LOG(debug) << "Reading CPUs for \"" << val.second.data() << "\"";
std::set<int> cpuVec = parseCpuString(cpus.get().data());
_templateCpus.insert(templateCpuMap_t::value_type(val.second.data(), cpuVec));
}
//group which consists of only one sensor
PerfSensorBase* sensor = new PerfSensorBase(val.second.data());
if (readSensorBase(*sensor, val.second)) {
group->pushBackSensor(sensor);
auto ret = _templateSensorGroups.insert(std::pair<std::string, PerfSensorGroup*>(val.second.data(), group));
if(!ret.second) {
LOG(warning) << "Template single " << _baseName << " " << val.second.data() << " already exists! Omitting...";
delete group;
}
} else {
LOG(warning) << "Template single " << _baseName << " " << val.second.data() << " could not be read! Omitting";
delete sensor;
delete group;
}
} else {
LOG(warning) << "Template single " << _baseName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
delete group;
}
}
} else if (boost::iequals(val.first, _groupName)) {
LOG(debug) << _groupName << " \"" << val.second.data() << "\"";
if (!val.second.empty()) {
PerfSensorGroup group(val.second.data());
if (readSensorGroup(group, val.second)) {
//now for the cpus...
//initialize set with cpuIDs
//default cpuSet: contains all cpuIDs
std::set<int> cpuSet;
for (int i = 0; i < get_nprocs(); i++) {
cpuSet.insert(i);
}
//check if (differing) cpus-list is given; if so, overwrite default cpuVec
boost::optional<boost::property_tree::iptree&> cpus = val.second.get_child_optional("cpus");
if (cpus) { //cpu list given
cpuSet = parseCpuString(cpus.get().data());
} else { //cpu list not given, but perhaps template counter has one
boost::optional<boost::property_tree::iptree&> def = val.second.get_child_optional("default");
if (def) {
templateCpuMap_t::iterator itC = _templateCpus.find(def.get().data());
if(itC != _templateCpus.end()) {
cpuSet = itC->second;
}
}
}
if (group.getMqttPart().size() == 0) {
LOG(warning) << _groupName << " \"" << val.second.data() << "\" has no mqttPart entry set. This is required as a place holder for the CPU id!";
}
//customize perfCounterGroup for every CPU
for (auto i : cpuSet) {
PerfSensorGroup* perfSG = new PerfSensorGroup(group);
perfSG->setGroupName(SensorBase::formatName(perfSG->getGroupName(), i));
perfSG->setCpuId(i);
perfSG->setMqttPart(formatMqttCPU(group.getMqttPart(), i) + "/");
for(auto s : perfSG->getSensors()) s->setName(s->getName(), i);
storeSensorGroup(perfSG);
}
customizeAndStore(group, val.second);
} else {
LOG(warning) << _groupName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
}
}
//single sensor
} else if (boost::iequals(val.first, "single_" + _baseName)) {
LOG(debug) << "Single " << _baseName << " \"" << val.second.data() << "\"";
if (!val.second.empty()) {
PerfSensorGroup group(val.second.data());
if (readSensorGroup(group, val.second)) {
//group which consists of only one sensor
PerfSensorBase* sensor;
//perhaps one sensor is already present because it was copied from the template group
if (group.getSensors().size() != 0) {
sensor = dynamic_cast<PerfSensorBase*>(group.getSensors()[0]);
sensor->setName(val.second.data());
if (readSensorBase(*sensor, val.second)) {
customizeAndStore(group, val.second);
} else {
LOG(warning) << "Single " << _baseName << " " << val.second.data() << " could not be read! Omitting";
}
} else {
sensor = new PerfSensorBase(val.second.data());
if (readSensorBase(*sensor, val.second)) {
group.pushBackSensor(sensor);
customizeAndStore(group, val.second);
} else {
LOG(warning) << "Single " << _baseName << " " << val.second.data() << " could not be read! Omitting";
delete sensor;
}
}
} else {
LOG(warning) << "Single " << _baseName << " \"" << val.second.data() << "\" has bad values! Ignoring...";
}
}
} else {
LOG(error) << "\"" << val.first << "\": unknown construct!";
return false;
......@@ -191,3 +222,42 @@ bool PerfeventConfigurator::readConfig(std::string cfgPath) {
_templateCpus.clear();
return true;
}
void PerfeventConfigurator::customizeAndStore(PerfSensorGroup& group, CFG_VAL cfg) {
//initialize set with cpuIDs
//default cpuSet: contains all cpuIDs
std::set<int> cpuSet;
for (int i = 0; i < get_nprocs(); i++) {
cpuSet.insert(i);
}
//check if (differing) cpus-list is given; if so, overwrite default cpuVec
boost::optional<boost::property_tree::iptree&> cpus = cfg.get_child_optional("cpus");
if (cpus) { //cpu list given
cpuSet = parseCpuString(cpus.get().data());
} else { //cpu list not given, but perhaps template counter has one
boost::optional<boost::property_tree::iptree&> def = cfg.get_child_optional("default");
if (def) {
templateCpuMap_t::iterator itC = _templateCpus.find(def.get().data());
if(itC != _templateCpus.end()) {
cpuSet = itC->second;
}
}
}
if (group.getMqttPart().size() == 0) {
LOG(warning) << _groupName << " \"" << cfg.data() << "\" has no mqttPart entry set. This is required as a place holder for the CPU id!";
}
//customize perfCounterGroup for every CPU
for (auto i : cpuSet) {
PerfSensorGroup* perfSG = new PerfSensorGroup(group);
perfSG->setGroupName(SensorBase::formatName(perfSG->getGroupName(), i));
perfSG->setCpuId(i);
perfSG->setMqttPart(formatMqttCPU(group.getMqttPart(), i) + "/");
for(auto s : perfSG->getSensors()) s->setName(s->getName(), i);
storeSensorGroup(perfSG);
}
}
......@@ -29,6 +29,17 @@ protected:
bool readConfig(std::string cfgPath) override;
private:
/**
* Takes a PerfSensorGroup and duplicates it for every CPU specified.
* Assigns one CPU value to every newly constructed group and stores them
* afterwards.
*
* @param group PerfSensorGroup which is to be customized for every CPU
* @param cfg Config tree for the group. Required to read in possibly
* differing CPU lists and default groups.
*/
void customizeAndStore(PerfSensorGroup& group, CFG_VAL cfg);
templateCpuMap_t _templateCpus;
enumMap_t _enumType;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment