aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcus Müller <mmueller@gnuradio.org>2021-07-16 19:22:21 +0200
committermormj <34754695+mormj@users.noreply.github.com>2021-07-27 11:21:52 -0400
commitf6b3295ae29e3ee3c2c8fc3c6738ee4561ca194b (patch)
tree31b557f0cdc3990deb104a33291be48606915301
parentdigital: more details in constellation test (diff)
downloadgnuradio-f6b3295ae29e3ee3c2c8fc3c6738ee4561ca194b.tar.xz
gnuradio-f6b3295ae29e3ee3c2c8fc3c6738ee4561ca194b.zip
digital/chunks to symbols: be less inefficient
The block formerly took the tags from get_tags_in_range (which are sorted), gave them to tag_checker, which sorted them, and then went through every input sample, checking its index against the next tag. Removed the tag_checker; that saves us a sorting of a sorted vector. The other optimization is to not dispatch any tag encountered to the own message handler; instead, the handler is called directly. Signed-off-by: Marcus Müller <mmueller@gnuradio.org>
-rw-r--r--gr-digital/include/gnuradio/digital/chunks_to_symbols.h4
-rw-r--r--gr-digital/lib/chunks_to_symbols_impl.cc70
-rw-r--r--gr-digital/lib/chunks_to_symbols_impl.h11
-rw-r--r--gr-digital/python/digital/bindings/chunks_to_symbols_python.cc2
4 files changed, 53 insertions, 34 deletions
diff --git a/gr-digital/include/gnuradio/digital/chunks_to_symbols.h b/gr-digital/include/gnuradio/digital/chunks_to_symbols.h
index 950977cdd..591c6afd7 100644
--- a/gr-digital/include/gnuradio/digital/chunks_to_symbols.h
+++ b/gr-digital/include/gnuradio/digital/chunks_to_symbols.h
@@ -51,9 +51,9 @@ public:
* \param symbol_table: list that maps chunks to symbols.
* \param D: dimension of table.
*/
- static sptr make(const std::vector<OUT_T>& symbol_table, const int D = 1);
+ static sptr make(const std::vector<OUT_T>& symbol_table, const unsigned int D = 1);
- virtual int D() const = 0;
+ virtual unsigned int D() const = 0;
virtual std::vector<OUT_T> symbol_table() const = 0;
virtual void set_symbol_table(const std::vector<OUT_T>& symbol_table) = 0;
};
diff --git a/gr-digital/lib/chunks_to_symbols_impl.cc b/gr-digital/lib/chunks_to_symbols_impl.cc
index 76bcac882..42a8217fb 100644
--- a/gr-digital/lib/chunks_to_symbols_impl.cc
+++ b/gr-digital/lib/chunks_to_symbols_impl.cc
@@ -14,7 +14,7 @@
#include "chunks_to_symbols_impl.h"
#include <gnuradio/io_signature.h>
-#include <gnuradio/tag_checker.h>
+#include <pmt/pmt.h>
#include <cassert>
namespace gr {
@@ -22,14 +22,15 @@ namespace digital {
void set_vector_from_pmt(std::vector<gr_complex>& symbol_table,
- pmt::pmt_t& symbol_table_pmt)
+ const pmt::pmt_t& symbol_table_pmt)
{
size_t length;
const gr_complex* elements = pmt::c32vector_elements(symbol_table_pmt, length);
symbol_table.assign(elements, elements + length);
}
-void set_vector_from_pmt(std::vector<float>& symbol_table, pmt::pmt_t& symbol_table_pmt)
+void set_vector_from_pmt(std::vector<float>& symbol_table,
+ const pmt::pmt_t& symbol_table_pmt)
{
size_t length;
const float* elements = pmt::f32vector_elements(symbol_table_pmt, length);
@@ -38,7 +39,8 @@ void set_vector_from_pmt(std::vector<float>& symbol_table, pmt::pmt_t& symbol_ta
template <class IN_T, class OUT_T>
typename chunks_to_symbols<IN_T, OUT_T>::sptr
-chunks_to_symbols<IN_T, OUT_T>::make(const std::vector<OUT_T>& symbol_table, const int D)
+chunks_to_symbols<IN_T, OUT_T>::make(const std::vector<OUT_T>& symbol_table,
+ const unsigned int D)
{
return gnuradio::make_block_sptr<chunks_to_symbols_impl<IN_T, OUT_T>>(symbol_table,
D);
@@ -46,17 +48,19 @@ chunks_to_symbols<IN_T, OUT_T>::make(const std::vector<OUT_T>& symbol_table, con
template <class IN_T, class OUT_T>
chunks_to_symbols_impl<IN_T, OUT_T>::chunks_to_symbols_impl(
- const std::vector<OUT_T>& symbol_table, const int D)
+ const std::vector<OUT_T>& symbol_table, const unsigned int D)
: sync_interpolator("chunks_to_symbols",
io_signature::make(1, -1, sizeof(IN_T)),
io_signature::make(1, -1, sizeof(OUT_T)),
D),
d_D(D),
- d_symbol_table(symbol_table)
+ d_symbol_table(symbol_table),
+ symbol_table_key(pmt::mp("set_symbol_table"))
{
- this->message_port_register_in(pmt::mp("set_symbol_table"));
- this->set_msg_handler(pmt::mp("set_symbol_table"),
- [this](pmt::pmt_t msg) { this->handle_set_symbol_table(msg); });
+ this->message_port_register_in(symbol_table_key);
+ this->set_msg_handler(symbol_table_key, [this](const pmt::pmt_t& msg) {
+ this->handle_set_symbol_table(msg);
+ });
}
template <class IN_T, class OUT_T>
@@ -66,7 +70,7 @@ chunks_to_symbols_impl<IN_T, OUT_T>::~chunks_to_symbols_impl()
template <class IN_T, class OUT_T>
void chunks_to_symbols_impl<IN_T, OUT_T>::handle_set_symbol_table(
- pmt::pmt_t symbol_table_pmt)
+ const pmt::pmt_t& symbol_table_pmt)
{
set_vector_from_pmt(d_symbol_table, symbol_table_pmt);
}
@@ -86,31 +90,43 @@ int chunks_to_symbols_impl<IN_T, OUT_T>::work(int noutput_items,
gr_vector_void_star& output_items)
{
gr::thread::scoped_lock lock(this->d_setlock);
- assert(noutput_items % d_D == 0);
- assert(input_items.size() == output_items.size());
- int nstreams = input_items.size();
+ auto nstreams = input_items.size();
+ for (unsigned int m = 0; m < nstreams; m++) {
+ const auto* in = reinterpret_cast<const IN_T*>(input_items[m]);
+ // NB: The compiler can't know whether all specializations of `chunks_to_symbol`
+ // are subclasses of gr::block. Hence the "this->" hoop we have to jump through to
+ // access members of parent classes.
+ size_t in_count = this->nitems_read(m);
- for (int m = 0; m < nstreams; m++) {
- const IN_T* in = (IN_T*)input_items[m];
- OUT_T* out = (OUT_T*)output_items[m];
+ auto out = reinterpret_cast<OUT_T*>(output_items[m]);
std::vector<tag_t> tags;
this->get_tags_in_range(
tags, m, this->nitems_read(m), this->nitems_read(m) + noutput_items / d_D);
- tag_checker tchecker(tags);
- // per stream processing
- for (int i = 0; i < noutput_items / d_D; i++) {
+ // per tag: all the samples leading up to this tag can be handled straightforward
+ // with the current settings
+ for (const auto& tag : tags) {
+ for (; in_count < tag.offset; ++in_count) {
+ auto key = static_cast<unsigned int>(*in) * d_D;
+ for (unsigned int idx = 0; idx < d_D; ++idx) {
+ *out = d_symbol_table[key + idx];
+ ++out;
+ }
+ ++in;
+ }
+ if (tag.key == symbol_table_key) {
+ handle_set_symbol_table(tag.value);
+ }
+ }
- std::vector<tag_t> tags_now;
- tchecker.get_tags(tags_now, i + this->nitems_read(m));
- for (unsigned int j = 0; j < tags_now.size(); j++) {
- tag_t tag = tags_now[j];
- this->dispatch_msg(tag.key, tag.value);
+ // after the last tag, continue working on the remaining items
+ for (; in < reinterpret_cast<const IN_T*>(input_items[m]) + noutput_items; ++in) {
+ auto key = static_cast<unsigned int>(*in) * d_D;
+ for (unsigned int idx = 0; idx < d_D; ++idx) {
+ *out = d_symbol_table[key + idx];
+ ++out;
}
- assert(((unsigned int)in[i] * d_D + d_D) <= d_symbol_table.size());
- memcpy(out, &d_symbol_table[(unsigned int)in[i] * d_D], d_D * sizeof(OUT_T));
- out += d_D;
}
}
return noutput_items;
diff --git a/gr-digital/lib/chunks_to_symbols_impl.h b/gr-digital/lib/chunks_to_symbols_impl.h
index a16b05a70..8800ebdbf 100644
--- a/gr-digital/lib/chunks_to_symbols_impl.h
+++ b/gr-digital/lib/chunks_to_symbols_impl.h
@@ -12,6 +12,7 @@
#define CHUNKS_TO_SYMBOLS_IMPL_H
#include <gnuradio/digital/chunks_to_symbols.h>
+#include <pmt/pmt.h>
namespace gr {
namespace digital {
@@ -20,18 +21,20 @@ template <class IN_T, class OUT_T>
class chunks_to_symbols_impl : public chunks_to_symbols<IN_T, OUT_T>
{
private:
- const int d_D;
+ const unsigned int d_D;
std::vector<OUT_T> d_symbol_table;
+ const pmt::pmt_t symbol_table_key;
public:
- chunks_to_symbols_impl(const std::vector<OUT_T>& symbol_table, const int D = 1);
+ chunks_to_symbols_impl(const std::vector<OUT_T>& symbol_table,
+ const unsigned int D = 1);
~chunks_to_symbols_impl() override;
- void handle_set_symbol_table(pmt::pmt_t symbol_table_pmt);
+ void handle_set_symbol_table(const pmt::pmt_t& symbol_table_pmt);
void set_symbol_table(const std::vector<OUT_T>& symbol_table) override;
- int D() const override { return d_D; }
+ unsigned int D() const override { return d_D; }
std::vector<OUT_T> symbol_table() const override { return d_symbol_table; }
int work(int noutput_items,
diff --git a/gr-digital/python/digital/bindings/chunks_to_symbols_python.cc b/gr-digital/python/digital/bindings/chunks_to_symbols_python.cc
index 284e1043a..3586b33e0 100644
--- a/gr-digital/python/digital/bindings/chunks_to_symbols_python.cc
+++ b/gr-digital/python/digital/bindings/chunks_to_symbols_python.cc
@@ -14,7 +14,7 @@
/* BINDTOOL_GEN_AUTOMATIC(0) */
/* BINDTOOL_USE_PYGCCXML(0) */
/* BINDTOOL_HEADER_FILE(chunks_to_symbols.h) */
-/* BINDTOOL_HEADER_FILE_HASH(92d3e85da4622d93c34d8226cbaaecf0) */
+/* BINDTOOL_HEADER_FILE_HASH(a7e4da5deb77580b19fd40a649ee11a8) */
/***********************************************************************************/
#include <pybind11/complex.h>