discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] Understanding processing delay


From: Marcus Müller
Subject: Re: [Discuss-gnuradio] Understanding processing delay
Date: Wed, 21 Oct 2015 12:11:12 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0

Hi Veljko,

GNU Radio works by calling your blocks' "work" methods with buffers full of consecutive items (read: samples). These blocks might then run in parallel. For example, assume that the first add_const has worked through samples 0-999, the second is called with the resulting 1000 items, while the first already starts to consume the 1000-1999 item coming from your source.
The probe block always takes the last item it gets in such an item chunk and memorizes it. Since these chunk sizes need not be constant, and processing is timing-wise totally unconnected to when you query the probes, it might be totally random what you're seeing.

So the interesting point here is: what were you *hoping* to find out with your flow graph?

Now, the subject line of your mail suggests you want to find out how long it takes for samples to propagate from source to sink -- I'd recommend using the "ctrlport monitor" to figure out how long the average calls to work lasted, and how many samples the work functions processed on average -- that'll tell you something like "for 4096, on average, my block needed 200µs". You could divide that down to give you a "latency per sample", but honestly, considering that you never process individual samples in GNU Radio, that would be meaningless, and also misleading, because it'd hide the "chunky" processing behaviour.

Best regards,
Marcus

On 20.10.2015 18:37, Veljko Pejovic wrote:
Hi,

In order to better understand the gnuradio flowgraph I created a very
simple test in which I connected a vector source (running through
1,2,3,4,5,6,7,8,9,0) in series with two “Add Const” blocks. The first
block adds 1, the second subtracts 1. I have two probes that I query
every second. One probe is connected directly to the vector source,
the other to the output of the second “Add Const” block. I print the
output of both probes every second. This is what I get from one run
(printing probe at the end, followed by the probe at the source):

$ python test_delay.py
0.0 0.0
Press Enter to quit: 2.0 5.0
5.0 9.0
7.0 2.0
2.0 6.0
4.0 8.0
0.0 2.0
4.0 7.0
8.0 1.0
0.0 5.0
0.0 3.0
8.0 1.0
4.0 8.0
4.0 9.0
8.0 1.0
0.0 4.0
7.0 0.0
6.0 9.0
5.0 8.0
3.0 6.0
5.0 8.0
8.0 2.0
3.0 4.0
8.0 3.0

and so on.

Two things surprise me here:
1) The output is different every time I run the graph.
2) The difference between the probe at the end of the second "Add
Const" element and the probe at the vector source is not constant. See
for example pairs: 0.0,2.0 , 0.0,5.0 and 0.0,3.0 all of which can be
seen in the output.

Can someone please explain this non-deterministic behaviour?

Thanks,

Veljko

p.s. attached is a screenshot of the GRC file I started from, and
here's the python code (slightly modified from the GRC):

from gnuradio import eng_notation
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
import threading
import time

class test_delay(gr.top_block):

    def __init__(self):
        gr.top_block.__init__(self, "Test Delay")

        self.variable_function_probe_0 = variable_function_probe_0 = 0
        self.samp_rate = samp_rate = 1

        self.probe = blocks.probe_signal_f()
        self.probe_src = blocks.probe_signal_f()
        def _variable_function_probe_0_probe():
            while True:
                val = self.probe.level()
                val_src = self.probe_src.level()
                print val, val_src
                try:
                    self.set_variable_function_probe_0(val)
                except AttributeError:
                    pass
                time.sleep(1.0 / (1))
        _variable_function_probe_0_thread =
threading.Thread(target=_variable_function_probe_0_probe)
        _variable_function_probe_0_thread.daemon = True
        _variable_function_probe_0_thread.start()
        self.blocks_vector_source_x_0 = blocks.vector_source_f((1, 2,
3, 4, 5, 6, 7, 8, 9, 0), True, 1, [])
        self.blocks_add_const_vxx_1 = blocks.add_const_vff((-1, ))
        self.blocks_add_const_vxx_0 = blocks.add_const_vff((1, ))

        self.connect((self.blocks_add_const_vxx_0, 0),
(self.blocks_add_const_vxx_1, 0))
        self.connect((self.blocks_add_const_vxx_1, 0), (self.probe, 0))
        self.connect((self.blocks_vector_source_x_0, 0),
(self.blocks_add_const_vxx_0, 0))
        self.connect((self.blocks_vector_source_x_0, 0), (self.probe_src, 0))

    def get_variable_function_probe_0(self):
        return self.variable_function_probe_0

    def set_variable_function_probe_0(self, variable_function_probe_0):
        self.variable_function_probe_0 = variable_function_probe_0

    def get_samp_rate(self):
        return self.samp_rate

    def set_samp_rate(self, samp_rate):
        self.samp_rate = samp_rate

if __name__ == '__main__':
    parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
    (options, args) = parser.parse_args()
    tb = test_delay()
    tb.start()
    try:
        raw_input('Press Enter to quit: ')
    except EOFError:
        pass
    tb.stop()
    tb.wait()


_______________________________________________
Discuss-gnuradio mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio


reply via email to

[Prev in Thread] Current Thread [Next in Thread]