diff --git a/Makefile b/Makefile index 085f3aa..a0a4cea 100644 --- a/Makefile +++ b/Makefile @@ -48,10 +48,25 @@ ifeq "$(DEBUG)" "true" GCOV?=gcov endif else - DEBUG_FLAGS=-Os -g - STRIP_BINARY=cp $(BUILD)/wmbusmeters $(BUILD)/wmbusmeters.g; $(STRIP) $(BUILD)/wmbusmeters - STRIP_ADMIN=cp $(BUILD)/wmbusmeters-admin $(BUILD)/wmbusmeters-admin.g; $(STRIP) $(BUILD)/wmbusmeters-admin - GCOV=To_run_gcov_add_DEBUG=true + ifeq "$(PROFILE)" "true" + DEBUG_FLAGS=-O0 -ggdb -fno-omit-frame-pointer -fprofile-arcs -pg + STRIP_BINARY= + STRIP_ADMIN= + BUILD:=$(BUILD)_profile + ifneq '' '$(findstring clang++,$(CXX))' + DEBUG_LDFLAGS= + GCOV=To_run_gcov_add_DEBUG=true + else + DEBUG_LDFLAGS=-lgcov --coverage + GCOV=To_run_gcov_add_DEBUG=true + endif + else + # Release build + DEBUG_FLAGS=-Os -g + STRIP_BINARY=cp $(BUILD)/wmbusmeters $(BUILD)/wmbusmeters.g; $(STRIP) $(BUILD)/wmbusmeters + STRIP_ADMIN=cp $(BUILD)/wmbusmeters-admin $(BUILD)/wmbusmeters-admin.g; $(STRIP) $(BUILD)/wmbusmeters-admin + GCOV=To_run_gcov_add_DEBUG=true + endif endif $(shell mkdir -p $(BUILD)) @@ -268,7 +283,7 @@ clean_executables: testoutput/test_stderr.txt clean: - rm -rf build/* build_arm/* build_debug/* build_arm_debug/* *~ + rm -rf build/* build_arm/* build_debug/* build_arm_debug/* build_profile/* *~ $(RM) testaes/test_input.txt testaes/test_stderr.txt $(RM) testoutput/test_expected.txt testoutput/test_input.txt \ testoutput/test_response.txt testoutput/test_responses.txt \ diff --git a/src/cmdline.cc b/src/cmdline.cc index bbd3919..51a4f65 100644 --- a/src/cmdline.cc +++ b/src/cmdline.cc @@ -203,6 +203,12 @@ static shared_ptr parseNormalCommandLine(Configuration *c, int ar i++; continue; } + if (!strncmp(argv[i], "--profile=", 10)) { + c->analyze_profile = atoi(argv[i]+10); + if (c->analyze_profile <= 0) error("Illegal profile value, must be greater than zero.\n"); + i++; + continue; + } if (!strncmp(argv[i], "--donotprobe=", 13)) { string df = string(argv[i]+13); diff --git a/src/config.h b/src/config.h index 952b29a..7004d40 100644 --- a/src/config.h +++ b/src/config.h @@ -78,6 +78,7 @@ struct Configuration string analyze_driver {}; string analyze_key {}; bool analyze_verbose {}; + int analyze_profile {}; // If greater than 0, then run the handleTelegram call this number of times when analyzing. bool debug {}; bool trace {}; AddLogTimestamps addtimestamps {}; diff --git a/src/main.cc b/src/main.cc index c8f9dc4..fc09fce 100644 --- a/src/main.cc +++ b/src/main.cc @@ -538,7 +538,8 @@ bool start(Configuration *config) config->analyze_format, config->analyze_driver, config->analyze_key, - config->analyze_verbose); + config->analyze_verbose, + config->analyze_profile); // The bus manager detects new/lost wmbus devices and // configures the devices according to the specification. diff --git a/src/metermanager.cc b/src/metermanager.cc index 2649488..920f3e9 100644 --- a/src/metermanager.cc +++ b/src/metermanager.cc @@ -24,6 +24,7 @@ #include"wmbus_utils.h" #include +#include #include #include #include @@ -37,6 +38,7 @@ struct MeterManagerImplementation : public virtual MeterManager private: bool is_daemon_ {}; bool should_analyze_ {}; + int should_profile_ {}; OutputFormat analyze_format_ {}; string analyze_driver_; string analyze_key_; @@ -272,9 +274,10 @@ public: } } - void analyzeEnabled(bool b, OutputFormat f, string force_driver, string key, bool verbose) + void analyzeEnabled(bool b, OutputFormat f, string force_driver, string key, bool verbose, int profile) { should_analyze_ = b; + should_profile_ = profile; analyze_format_ = f; if (force_driver != "auto") { @@ -434,6 +437,45 @@ public: bool match = false; string id; + if (should_profile_ > 0) + { + size_t start_peak_rss = getPeakRSS(); + size_t start_curr_rss = getCurrentRSS(); + string start_peak_prss = humanReadableTwoDecimals(start_peak_rss); + + notice("Profiling %d rounds memory rss %zu peak %s\n", should_profile_, start_curr_rss, start_peak_prss.c_str()); + + chrono::milliseconds start = chrono::duration_cast< chrono::milliseconds >(chrono::system_clock::now().time_since_epoch()); + + for (int k=0; khandleTelegram(about, input_frame, simulated, &id, &match, &t); + string hr, fields, json; + vector envs, more_json, selected_fields; + + meter->printMeter(&t, &hr, &fields, '\t', &json, + &envs, &more_json, &selected_fields, true); + if (k % 100 == 0) fprintf(stderr, "."); + } + + chrono::milliseconds end = chrono::duration_cast< chrono::milliseconds >(chrono::system_clock::now().time_since_epoch()); + + size_t end_peak_rss = getPeakRSS(); + size_t end_curr_rss = getCurrentRSS(); + string end_peak_prss = humanReadableTwoDecimals(end_peak_rss); + + std::chrono::duration diff_s(end-start); + + double speed_ms = 1000.0 * (diff_s.count()) / should_profile_; + + notice("\nDone profiling after %g s which gives %g ms/telegram memory rss %zu peak %s\n", + diff_s.count(), + speed_ms, + end_curr_rss, + end_peak_prss.c_str()); + return; + } + meter->handleTelegram(about, input_frame, simulated, &id, &match, &t); int u = 0; diff --git a/src/meters.h b/src/meters.h index d686ca0..2ddbf6e 100644 --- a/src/meters.h +++ b/src/meters.h @@ -447,7 +447,7 @@ struct MeterManager virtual void onTelegram(function)> cb) = 0; virtual void whenMeterUpdated(std::function cb) = 0; virtual void pollMeters(shared_ptr bus) = 0; - virtual void analyzeEnabled(bool b, OutputFormat f, string force_driver, string key, bool verbose) = 0; + virtual void analyzeEnabled(bool b, OutputFormat f, string force_driver, string key, bool verbose, int profile) = 0; virtual void analyzeTelegram(AboutTelegram &about, vector &input_frame, bool simulated) = 0; virtual ~MeterManager() = default;