summaryrefslogtreecommitdiff
path: root/gr-blocks/python
diff options
context:
space:
mode:
authorThomas Habets <thomas@habets.se>2020-06-07 18:52:22 +0100
committermormj <34754695+mormj@users.noreply.github.com>2020-06-15 08:21:35 -0400
commit518aa489498ec692dee51bb69936b620660ba113 (patch)
tree49ff128f6549ad7d91eb11020d85581f292f3f1b /gr-blocks/python
parentef825aad904b9a5ff99160d7f38181eb175137eb (diff)
blocks/moving_average: use vector functions
This improves performance of moving average for me by about 4-5x. My test is [here](https://github.com/ThomasHabets/radiostuff/blob/master/amateur/listen_70cm.grc), which processes 10MHz to find the strongest signal. Without this PR I see `moving_average` in `top` taking about 89.4-94% CPU. With this patch it's ~20.4-23.7%. Since without this patch it's that high, I don't know that it's not even better. Test measured on a Libremv2 with Intel Core i7-6500U @ 2.5GHz. The memory access pattern is probably worse with this patch, but at least on my hardware on my workload this seems to be dwarfed by the gain of using volk. It can be hard to reason about memory access patterns, so benchmarks overrule theory. The test only actually uses float averaging. More benchmarking may be required. Possible improvements: * Add template specialization for `uint16` and `uint32`? * Refactor for non-volk fallback to use only one loop, with (presumably) better memory access pattern)
Diffstat (limited to 'gr-blocks/python')
-rw-r--r--gr-blocks/python/blocks/qa_moving_average.py35
1 files changed, 32 insertions, 3 deletions
diff --git a/gr-blocks/python/blocks/qa_moving_average.py b/gr-blocks/python/blocks/qa_moving_average.py
index 7f9aa57770..4319b40b01 100644
--- a/gr-blocks/python/blocks/qa_moving_average.py
+++ b/gr-blocks/python/blocks/qa_moving_average.py
@@ -81,7 +81,7 @@ class test_moving_average(gr_unittest.TestCase):
# This tests implement own moving average to verify correct behaviour of the block
- def test_03(self):
+ def test_vector_int(self):
tb = self.tb
vlen = 5
@@ -111,7 +111,36 @@ class test_moving_average(gr_unittest.TestCase):
# make sure result is close to zero
self.assertTupleEqual(dut_data, ref_data)
- def test_04(self):
+ def test_vector_complex(self):
+ tb = self.tb
+
+ vlen = 5
+ N = 10*vlen
+ data = make_random_complex_tuple(N, 2**10)
+ src = blocks.vector_source_c(data, False)
+ one_to_many = blocks.stream_to_streams(gr.sizeof_gr_complex, vlen)
+ one_to_vector = blocks.stream_to_vector(gr.sizeof_gr_complex, vlen)
+ many_to_vector = blocks.streams_to_vector(gr.sizeof_gr_complex, vlen)
+ isolated = [ blocks.moving_average_cc(100, 1) for i in range(vlen)]
+ dut = blocks.moving_average_cc(100, 1, vlen=vlen)
+ dut_dst = blocks.vector_sink_c(vlen=vlen)
+ ref_dst = blocks.vector_sink_c(vlen=vlen)
+
+ tb.connect(src, one_to_many)
+ tb.connect(src, one_to_vector, dut, dut_dst)
+ tb.connect(many_to_vector, ref_dst)
+ for idx, single in enumerate(isolated):
+ tb.connect((one_to_many,idx), single, (many_to_vector,idx))
+
+ tb.run()
+
+ dut_data = dut_dst.data()
+ ref_data = ref_dst.data()
+
+ # make sure result is close to zero
+ self.assertTupleEqual(dut_data, ref_data)
+
+ def test_complex_scalar(self):
tb = self.tb
N = 10000 # number of samples
@@ -119,7 +148,7 @@ class test_moving_average(gr_unittest.TestCase):
data = make_random_complex_tuple(N, 1) # generate random data
# pythonic MA filter
- data_padded = (history-1)*[0.0+1j*0.0]+list(data) # history
+ data_padded = (history-1)*[complex(0.0, 0.0)]+list(data) # history
expected_result = []
moving_sum = sum(data_padded[:history-1])
for i in range(N):