Overrun when there shouldn't be


#1

Hi,

I wrote a c++ program that grabs data from the USRP in an infinite loop
and does nothing with it. It overruns. Can anyone help me figure out
why?

This runs on a 2.4GHz computer that isn’t doing anything else. I’m
sampling the A and B channel of a BasicRX at 4MHz with shorts. CPU runs
about 15%. I’ve tried many different values for NumBytes. Profile
results show nothing abnormal. This is driving me nuts!

Thank you,

Chris

#include <usrp_standard.h>
#include

using namespace std;

static const unsigned DecimRate = 16;

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int main(int argc, char** argv)
{

static const int UsrpNumber = 0;

const unsigned Format = usrp_standard_rx::make_format(
16, // width across usb
0, // shift
true, // want Q
false // bypass halfband
);

usrp_standard_rx* rx = usrp_standard_rx::make(UsrpNumber, DecimRate);

static const int Mux = 0x33221100;

rx->set_decim_rate(DecimRate);

static const double DdcFreq = -12000e3;

static const int NumChannels = 2;

rx->set_nchannels(NumChannels);

for(int i = 0; i < NumChannels; ++i)
{
rx->set_rx_freq(i, DdcFreq);
}

rx->set_mux(Mux);
rx->set_pga(0, 0);
rx->set_pga(1, 0);

rx->set_format(Format);

static const unsigned NumBytes = 4096;

char* Buffer = new char[NumBytes];

rx->start();

bool Overrun = false;

// Throw away first 32kB of data because it’s fouled up
// with some kind of sinc
int NumTossed = 0;
while(NumTossed < 32768)
{
NumTossed += rx->read(Buffer, NumBytes, &Overrun);
}

while(true)
{
rx->read(Buffer, NumBytes, &Overrun);

if(Overrun)
{
  Overrun = false;
  cerr << "Overrun\n";
}

//std::cout.write(Buffer, NumBytes);

}

rx->stop();

delete [] Buffer;

return 0;
}


#2

On Mon, Feb 09, 2009 at 07:07:56PM -0800, Chris S. wrote:

Thank you,

Chris

We’re not very good at reading minds. You’re more likely to get help
if you provide us some clues:

Which OS are you running on?
Are you running on a VM?
Did you build and install the GR code, or did you just extract the
usrp code and try to build it? In either base, which version are you
using?
Which FUSB method are you using?

Have you build GNU Radio and attempted to run usrp_rx_cfile.py?
Does it overrun?

Eric


#3

Eric B. wrote:

Which OS are you running on?
Are you running on a VM?
Did you build and install the GR code, or did you just extract the
usrp code and try to build it? In either base, which version are you using?
Which FUSB method are you using?

Have you build GNU Radio and attempted to run usrp_rx_cfile.py?
Does it overrun?

Thank you for your response.

  1. Ubuntu 8.10 32bit and Ubuntu 8.04 64 bit
  2. No VM
  3. Built and installed 3.1.3 (tar.gz)
  4. usrp_rx_cfile does not overrun (!)
  5. I do not know what “FUSB method” means, but I like the sounds of it.
    Looking it up now.

Chris


#4

Johnathan C. wrote:

On Mon, Feb 9, 2009 at 7:07 PM, Chris S. removed_email_address@domain.invalid wrote:

I wrote a c++ program that grabs data from the USRP in an infinite loop
and does nothing with it. It overruns. Can anyone help me figure out why?

Can you try it without the call to set_format()?

Johnathan,

Even without the call to set_format, I still get overruns. I also made
some other changes:

  1. Original code (overruns)
    1. minus set_format (overruns)
    1. with NumChannels==1 (no overruns)
    1. with DecimRate==32 vs 16 (no overruns)

Test 3 not overrunning was no surprise since it’s cuts the data in half.
However, Test 4 note overrunning was a huge surprise because Test 4
pumps the same amount of data as Test 2 which does overrun.

Question: Why would 2 channels at 4MHz overrun while 1 channel at 8MHz
not overrun?

Chris


#5

Chris S. wrote:

  1. Built and installed 3.1.3 (tar.gz)

Just upgraded to the trunk and unfortunately have the same problem.
(usrp_standard_rx* changed to a boost sptr, but otherwise code is the
same.)

Chris


#6

On Mon, Feb 9, 2009 at 7:07 PM, Chris S. removed_email_address@domain.invalid
wrote:

I wrote a c++ program that grabs data from the USRP in an infinite loop
and does nothing with it. It overruns. Can anyone help me figure out why?

Can you try it without the call to set_format()?

Johnathan


#7

On Mon, Feb 09, 2009 at 11:34:17PM -0800, Chris S. wrote:

Even without the call to set_format, I still get overruns. I also made

Question: Why would 2 channels at 4MHz overrun while 1 channel at 8MHz
not overrun?

Chris

Chris,

Try this:

#include <gr_realtime.h>

gr_enable_realtime_scheduling();

Be sure that you’re in the usrp group, and that
/etc/security/limits.conf contains this line:

@usrp - rtprio 50

If you edit /etc/security/limits.conf I’m pretty sure you need to
reboot to get it to take effect.

Eric


#8

Chris S. wrote:

overruns.

I’d love to help find the source of the problem in newer versions of
gnuradio… if anyone has any tests you’d like run, let me know.

Chris

Oooooh. That’s useful intelligence. I had the impression with my RA
stuff (loves bandwidth, the more Msps the better!) is
that the overrun issue became worse across gnuradio versions, but I
wasn’t sure (too lazy to regress everything and check!).

Fortunately for my RA stuff, a few dropped buffers now and then don’t
hurt–they simply constitute a tiny increase in
the noise floor.


Marcus L.
Principal Investigator, Shirleys Bay Radio Astronomy Consortium
http://www.sbrac.org


#9

Chris S. wrote:

Question: Why would 2 channels at 4MHz overrun while 1 channel at 8MHz
not overrun?

Fantastic news (for me): this problem does not occur in gnuradio 3.0.2

I thought to try an older version of gnuradio after I made the
realization (with the help of a coworker) that my overrun problems are
worse today than they were a year ago.

FYI, my application is a dual channel GPS receiver which demands no
overruns.

I’d love to help find the source of the problem in newer versions of
gnuradio… if anyone has any tests you’d like run, let me know.

Chris


#10

Juha V. wrote:

usrp_standard_rx* rx = usrp_standard_rx::make(UsrpNumber,
DecimRate,2,-1,0,4096,4096);

Using gnuradio 3.1.3 and applying the above change plus the
gr_enable_realtime_scheduling(); change fixed my problem. I should try
just making one of the two changes too to see which one does the trick.

Thanks for your help!

Chris


#11

Eric B. wrote am 2009-02-10 22:13:

Be sure that you’re in the usrp group, and that
/etc/security/limits.conf contains this line:

@usrp - rtprio 50

If you edit /etc/security/limits.conf I’m pretty sure you need to
reboot to get it to take effect.

You do not need need reboot[1].

Debian man page says:
Also, please note that all limit settings are set per login.
They
are not global, nor are they permanent;
existing only for the duration of the session.

A new login should do. This can mean loging in and out once, or just
saying

su $USER

will give you the new setting, but only in this session.

Patrick

[1] This is not Microsoft :wink:

Engineers motto: cheap, good, fast: choose any two
Patrick S.
Student of Telematik, Techn. University Graz, Austria


#12

Hi,

I tried your code and also got overruns. I have had better luck by
increasing the fusb_blocksize and fusb_nblocks to really large values
like fusb_blocksize=4096 and fusb_nblocks=4096 (or sometimes even
16384). In my opinion the default values are too small.

I made the following modification to your code. It takes care of the
overruns for me:

usrp_standard_rx* rx = usrp_standard_rx::make(UsrpNumber,
DecimRate,2,-1,0,4096,4096);

If I recall correctly, others have told me this is a stupid idea
because it uses up a lot of kernel space memory. I agree that this
might waste a couple of megabytes of RAM, but I have a lot of memory
and it is very important in my applications to sample without
overflows. Increasing fusb_nblocks is the only way that has
consistently worked for me. I have also tried the realtime stuff, but
it didn’t give very consistent results.

I actually challenge anyone to send me code that doesn’t overflow on
my computer (core2 duo macbook pro) during eigth hours of
full-bandwidth operation. The rules are no realtime scheduling, and
use the default fusb_nblocks and fusb_blocksize. The code should have
the same functionality as the code that Chris sent. I will buy a beer
to the first person that proves me wrong.

Others in the thread seem to have commented about the gradual
degradation in the performance of gnuradio. I can only report the
contrary. Gnuradio has only improved as a function of time. The
C-interfaces and multithreaded schedulers rock!

BR,
juha