discuss-gnuradio
[Top][All Lists]
Advanced

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

Re: [Discuss-gnuradio] profiling the waterfall


From: Dan Gisselquist
Subject: Re: [Discuss-gnuradio] profiling the waterfall
Date: Wed, 09 Mar 2005 15:23:58 +0000

Dave,

I've worked this problem a couple of times before. The fastest answer is not to plot every point. If you instead cluster points of the same color together, and then plot bars instead of points, the graphics algorithm will go much faster. A piece of some code that does this looks sort of like,

        // flo is the lowest frequency having my current color value
        // fvl is the value of the color that I have yet to plot on the screen
        // thisclr is a temporary of the color I'm currently looking at
        // i ranges across all frequencies from low to the fft-width
        // min is the minimum y value expected in the data, max is the
        //      maximum.  We'll linearly scale between them
       flo = 0; fvl = (int)((dat[0]-min)* (NUMCLRS-1) / (max-min) + 0.5);
       if (fvl < 0) fvl = 0; else if (fvl >= NUMCLRS) fvl=NUMCLRS-1;
       for(i=1; i<m_framelen; i++) {
               int     thisclr;

                // Find out what color is appropriate for this frequency
               thisclr = (int)((dat[i]-min)* (NUMCLRS-1) / (max-min) + 0.5);
               if (thisclr < 0) thisclr = 0;
               else if (thisclr >= NUMCLRS) thisclr=NUMCLRS-1;

                // If it's not the color we've been storing/buffering ...
                // then place a bar on the screen and reset the buffer.
               if (thisclr != fvl) {
                       bar(m_scrollpos, flo, i-1, fvl, m_framelen);
                       fvl = thisclr;
                       flo = i;
               }
       } bar(m_scrollpos, flo, m_framelen-1, fvl, m_framelen);

where bar(x_time, lo_freq, hi_freq, clr, total_len) just draws a bar on the screen of the solid color clr, between appropriately scaled y values of lo_freq and hi_freq. (These could just as easily be x values ...)

As long as you have bars of constant color, such as solid black regions of no activity, this technique works much better.

Hope this helps,

Dan

On 03/09/2005 01:46:44 AM, David Carr wrote:
I've spent some time profiling the waterfallsink code. Currently its pretty abominably slow. I'm using python's profile module to do the following.

For a given run:

total run time on cpu as reported by the command "time"
real    0m17.874s
user    0m16.364s
sys     0m0.883s

python profile module reported total run time:
8.06 sec (8.06 is 45% of 17.87)

Where does the rest of the time go?

Here's the 8.06 sec broken down:

set_data() 92%
   set_data_loop() 86%
       dc1.SetPen(dc1.SetPen(wx.Pen(colour, 1, wx.SOLID)) 51%
       dc1.SetBrush(wx.Brush(colour, wx.SOLID)) 28%
       dc1.DrawRectangle(x_pos*p_width, 0, p_width, 1) 7%
The offending code (broken into parts for profiling)

def set_data_loop_draw(self, dc1, x_pos, p_width, value):
       colour = wx.Colour(value, value, value)
       dc1.SetPen(wx.Pen(colour, 1, wx.SOLID))
       dc1.SetBrush(wx.Brush(colour, wx.SOLID))
       dc1.DrawRectangle(x_pos*p_width, 0, p_width, 1)

   def set_data_loop(self, dc1, dB, d_max, p_width):
       for x_pos in range(0, d_max):
               value = int(dB[x_pos] * 1.5)
               if value > 255:
                   value = 255
               elif value < 0:
                   value = 0
               self.set_data_loop_draw(dc1, x_pos, p_width, value)

   def set_data (self, evt):
       data = evt.data
       dB = 20 * Numeric.log10 (abs(data) + 1e-8)
       l = len (dB)
             dc1 = wx.MemoryDC()
       dc1.SelectObject(self.bm)
       dc1.Blit(0,1,self.info.fft_size,300,dc1,0,0,wx.COPY,False,-1,-1)

       if self.info.input_is_real:
           d_max = l/2
           p_width = 2
       else:
           d_max = l
           p_width = 1

           self.set_data_loop(dc1, dB, d_max, p_width)
            self.DoDrawing (None)

Where do we go from here? I should note that the loop is not actually that slow, its just gets iterates for every drawn pixel. That translates to 18,432 calls to the loop itself in 8.06 seconds at 512 iterations per call. Ideally this loop could be eliminated if there were a way to plot a vector rather than each point individually. That would be very nice indeed.

It would also be nice to know where the other 17 - 8.06 = ~9 seconds go that profiling doesn't account for...

-David Carr


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






reply via email to

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