From 156ee71cbb3c94d5d77a5afcc376cd512ce8fe9d Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Thu, 20 Apr 2017 23:47:30 +0200 Subject: Replace SSE check by march=native check --- configure.ac | 27 ++++++++-------------- src/Utils.cpp | 72 +++++++++++++++++++++++++++-------------------------------- 2 files changed, 42 insertions(+), 57 deletions(-) diff --git a/configure.ac b/configure.ac index cd6f0ed..acefa90 100644 --- a/configure.ac +++ b/configure.ac @@ -161,31 +161,22 @@ AC_COMPILE_IFELSE( AC_LANG_POP([C++]) -# Check for SSE -AC_MSG_CHECKING(for SSE in current arch/CFLAGS) +# Check for march +AC_MSG_CHECKING(if we can add -march=native to CFLAGS) save_CXXFLAGS="$CXXFLAGS" -CXXFLAGS="$CXXFLAGS -msse" -AC_MSG_CHECKING([whether we need to add -msse]) +CXXFLAGS="$CXXFLAGS -march=native" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ -#include -__m128 testfunc(float *a, float *b) { - return _mm_add_ps(_mm_loadu_ps(a), _mm_loadu_ps(b)); -} +void testfunc(void) {} ]])], -[has_sse=yes], -[has_sse=no] +[supports_march_native=yes], +[supports_march_native=no] ) -AC_MSG_RESULT($has_sse) -if test x"$has_sse" = xno; then +AC_MSG_RESULT($supports_march_native) +if test x"$supports_march_native" = xno; then CXXFLAGS="$save_CXXFLAGS" fi - -AM_CONDITIONAL([HAVE_SSE], [test "x$has_sse" = "xyes"]) - -# TODO: Check for NEON - AC_TYPE_SIGNAL AC_CHECK_FUNCS([bzero floor ftime gettimeofday memset sqrt strchr strerror strtol]) @@ -211,7 +202,7 @@ echo echo enabled="" disabled="" -for feat in with_debug_malloc has_sse enable_fast_math +for feat in with_debug_malloc supports_march_native enable_fast_math do eval var=\$$feat AS_IF([test "x$var" != "xno"], diff --git a/src/Utils.cpp b/src/Utils.cpp index 5bd93d9..cd116c7 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -30,18 +30,40 @@ #include #include -void printUsage(const char* progName) +static void printHeader() { - FILE* out = stderr; - - fprintf(out, "Welcome to %s %s, compiled at %s, %s\n\n", - PACKAGE, + std::cerr << "ODR-DabMod version " << #if defined(GITVERSION) - GITVERSION, + GITVERSION #else - VERSION, + VERSION +#endif + ", compiled at " << __DATE__ << ", " << __TIME__ << std::endl; + + std::cerr << "Compiled with features: " << +#if defined(HAVE_ZEROMQ) + "zeromq " << +#endif +#if defined(HAVE_OUTPUT_UHD) + "output_uhd " << #endif - __DATE__, __TIME__); +#if defined(HAVE_SOAPYSDR) + "output_soapysdr " << +#endif +#if defined(__FAST_MATH__) + "fast-math " << +#endif +#if defined(__SSE__) + "SSE " << +#endif + "\n"; +} + +void printUsage(const char* progName) +{ + printHeader(); + + FILE* out = stderr; fprintf(out, "Usage with configuration file:\n"); fprintf(out, "\t%s [-C] config_file.ini\n\n", progName); @@ -87,16 +109,9 @@ void printUsage(const char* progName) void printVersion(void) { - FILE *out = stderr; + printHeader(); - fprintf(out, "%s %s, compiled at %s, %s\n\n", - PACKAGE, -#if defined(GITVERSION) - GITVERSION -#else - VERSION -#endif - ,__DATE__, __TIME__); + FILE *out = stderr; fprintf(out, " ODR-DabMod is copyright (C) Her Majesty the Queen in Right of Canada,\n" " 2005 -- 2012 Communications Research Centre (CRC),\n" @@ -123,28 +138,7 @@ void printVersion(void) void printStartupInfo() { - std::cerr << "ODR-DabMod version " << -#if defined(GITVERSION) - GITVERSION -#else - VERSION -#endif - << std::endl; - - std::cerr << "Compiled with features: " << -#if defined(HAVE_ZEROMQ) - "zeromq " << -#endif -#if defined(HAVE_OUTPUT_UHD) - "output_uhd " << -#endif -#if defined(HAVE_SOAPYSDR) - "output_soapysdr " << -#endif -#if defined(__FAST_MATH__) - "fast-math" << -#endif - "\n"; + printHeader(); etiLog.level(info) << "Starting up version " << #if defined(GITVERSION) -- cgit v1.2.3 From 1810a2c6a34207caedf5a88bc4e5d38080e764ed Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 21 Apr 2017 00:07:22 +0200 Subject: Put UHD async msg to separate thread --- src/OutputUHD.cpp | 110 ++++++++++++++++++++++++++++-------------------------- src/OutputUHD.h | 6 ++- 2 files changed, 62 insertions(+), 54 deletions(-) diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index e4b57bc..6679e62 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -780,21 +780,6 @@ void UHDWorker::handle_frame(const struct UHDWorkerFrameData *frame) } tx_frame(frame, timestamp_discontinuity); - - auto time_now = std::chrono::steady_clock::now(); - if (last_print_time + std::chrono::seconds(1) < time_now) { - if (num_underflows or num_late_packets) { - etiLog.log(info, - "OutputUHD status (usrp time: %f): " - "%d underruns and %d late packets since last status.\n", - usrp_time, - num_underflows, num_late_packets); - } - num_underflows = 0; - num_late_packets = 0; - - last_print_time = time_now; - } } void UHDWorker::tx_frame(const struct UHDWorkerFrameData *frame, bool ts_update) @@ -834,51 +819,70 @@ void UHDWorker::tx_frame(const struct UHDWorkerFrameData *frame, bool ts_update) "UHDWorker::process() unable to write to device, skipping frame!\n"); break; } - - print_async_metadata(frame); } } -void UHDWorker::print_async_metadata(const struct UHDWorkerFrameData *frame) +void UHDWorker::print_async_metadata() { - uhd::async_metadata_t async_md; - if (uwd->myUsrp->get_device()->recv_async_msg(async_md, 0)) { - const char* uhd_async_message = ""; - bool failure = false; - switch (async_md.event_code) { - case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: - break; - case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: - uhd_async_message = "Underflow"; - num_underflows++; - break; - case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR: - uhd_async_message = "Packet loss between host and device."; - failure = true; - break; - case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: - uhd_async_message = "Packet had time that was late."; - num_late_packets++; - break; - case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET: - uhd_async_message = "Underflow occurred inside a packet."; - failure = true; - break; - case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST: - uhd_async_message = "Packet loss within a burst."; - failure = true; - break; - default: - uhd_async_message = "unknown event code"; - failure = true; - break; + while (uwd->running) { + uhd::async_metadata_t async_md; + if (uwd->myUsrp->get_device()->recv_async_msg(async_md, 1)) { + const char* uhd_async_message = ""; + bool failure = false; + switch (async_md.event_code) { + case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: + break; + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW: + uhd_async_message = "Underflow"; + num_underflows++; + break; + case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR: + uhd_async_message = "Packet loss between host and device."; + failure = true; + break; + case uhd::async_metadata_t::EVENT_CODE_TIME_ERROR: + uhd_async_message = "Packet had time that was late."; + num_late_packets++; + break; + case uhd::async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET: + uhd_async_message = "Underflow occurred inside a packet."; + failure = true; + break; + case uhd::async_metadata_t::EVENT_CODE_SEQ_ERROR_IN_BURST: + uhd_async_message = "Packet loss within a burst."; + failure = true; + break; + default: + uhd_async_message = "unknown event code"; + failure = true; + break; + } + + if (failure) { + etiLog.level(alert) << + "Received Async UHD Message '" << + uhd_async_message << "' at time " << + md.time_spec.get_real_secs(); + + } } - if (failure) { - etiLog.level(alert) << "Near frame " << - frame->ts.fct << ": Received Async UHD Message '" << - uhd_async_message << "'"; + auto time_now = std::chrono::steady_clock::now(); + if (last_print_time + std::chrono::seconds(1) < time_now) { + const double usrp_time = + uwd->myUsrp->get_time_now().get_real_secs(); + + if (num_underflows or num_late_packets) { + etiLog.log(info, + "OutputUHD status (usrp time: %f): " + "%d underruns and %d late packets since last status.\n", + usrp_time, + num_underflows, num_late_packets); + } + num_underflows = 0; + num_late_packets = 0; + last_print_time = time_now; } } } diff --git a/src/OutputUHD.h b/src/OutputUHD.h index cbf159f..d42245f 100644 --- a/src/OutputUHD.h +++ b/src/OutputUHD.h @@ -125,6 +125,8 @@ class UHDWorker { void start(struct UHDWorkerData *uhdworkerdata) { uwd->running = true; uhd_thread = boost::thread(&UHDWorker::process_errhandler, this); + async_rx_thread = boost::thread( + &UHDWorker::print_async_metadata, this); } void stop() { @@ -133,6 +135,7 @@ class UHDWorker { } uhd_thread.interrupt(); uhd_thread.join(); + async_rx_thread.join(); } ~UHDWorker() { @@ -155,13 +158,14 @@ class UHDWorker { // Used to print statistics once a second std::chrono::steady_clock::time_point last_print_time; - void print_async_metadata(const struct UHDWorkerFrameData *frame); + void print_async_metadata(void); void handle_frame(const struct UHDWorkerFrameData *frame); void tx_frame(const struct UHDWorkerFrameData *frame, bool ts_update); struct UHDWorkerData *uwd; boost::thread uhd_thread; + boost::thread async_rx_thread; uhd::tx_streamer::sptr myTxStream; -- cgit v1.2.3 From aabba6c6b56edbd4f64913af33651a2f2a641976 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 1 May 2017 06:22:25 +0200 Subject: Ensure buffer in OutputUHD is properly filled to reduce underruns --- src/OutputUHD.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index 6679e62..e835d6e 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -639,16 +639,29 @@ void UHDWorker::process() num_underflows = 0; num_late_packets = 0; + int last_num_underflows = 0; + size_t pop_prebuffering = FRAMES_MAX_SIZE; + while (uwd->running) { md.has_time_spec = false; md.time_spec = uhd::time_spec_t(0.0); struct UHDWorkerFrameData frame; etiLog.log(trace, "UHD,wait"); - uwd->frames.wait_and_pop(frame); + uwd->frames.wait_and_pop(frame, pop_prebuffering); etiLog.log(trace, "UHD,pop"); handle_frame(&frame); + + /* Ensure we fill uwd->frames after every underrun and + * at startup to reduce underrun likelihood. */ + if (last_num_underflows < num_underflows) { + pop_prebuffering = FRAMES_MAX_SIZE; + } + else { + pop_prebuffering = 1; + } + last_num_underflows = num_underflows; } } -- cgit v1.2.3 From bfce4874a0410f8f6521875d7e975f80d05544d4 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 1 May 2017 06:23:21 +0200 Subject: Reindent stringtrim in OutputUHD --- src/OutputUHD.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index e835d6e..d78c4bf 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -56,8 +56,12 @@ typedef std::complex complexf; std::string stringtrim(const std::string &s) { - auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c){return std::isspace(c);} ); - return std::string(wsfront, std::find_if_not(s.rbegin(), std::string::const_reverse_iterator(wsfront), [](int c){return std::isspace(c);} ).base()); + auto wsfront = std::find_if_not(s.begin(), s.end(), + [](int c){ return std::isspace(c);} ); + return std::string(wsfront, + std::find_if_not(s.rbegin(), + std::string::const_reverse_iterator(wsfront), + [](int c){ return std::isspace(c);} ).base()); } void uhd_msg_handler(uhd::msg::type_t type, const std::string &msg) -- cgit v1.2.3