pothosware / SoapyPlutoSDR

Soapy SDR plugin for PlutoSDR
https://github.com/pothosware/SoapyPlutoSDR/wiki
GNU Lesser General Public License v2.1
53 stars 22 forks source link

Pluto/gr-osmosdr: soapy_sink_cc thread uses ~15% CPU #27

Closed kantooon closed 4 years ago

kantooon commented 4 years ago

Crossref this ticket: https://github.com/kantooon/qradiolink/issues/43 Compared to the same sink used with a Lime mini, this CPU usage is quite huge. Seems to be specific of SoapyPlutoSDR, I'll look into this myself, but maybe someone else can find a solution faster.

zuckschwerdt commented 4 years ago

Can you add more info, which connection are you using (USB, network), what sample format, data rate?

kantooon commented 4 years ago

Ah yes, sorry I forgot these common sense details. The sample format is the standard GNU radio complex with 32 bit float. Transport is USB, not ethernet. The sample rate at which this was measured was 1 Msps. I have to say that the source uses more CPU than other devices as well, but not so much as the sink. As far as I can tell gr-osmosdr does nothing unusual that would justify this increased CPU consumption.

zuckschwerdt commented 4 years ago

The hardware format of the Pluto is CS16 and for TX it has to be scaled (the output is MSB aligned, scale=32768). Can you check if that is an issue? Though 1Msps should not burden a desktop CPU in any way.

Perhaps source and sink to the Pluto with different formats, using rx_tools rx_sdr (I added format options early this year) and perhaps tx_tools if you delete this line: https://github.com/zuckschwerdt/tx_tools/blob/master/src/tx_sdr.c#L244 (caveat emptor: I did a complete rewrite but it's not published yet).

kantooon commented 4 years ago

I'll check, but this is coming from GNU radio, I don't use any of this API directly. gr-osmosdr wraps and abstracts all these devices including Soapy devices nicely. Also CPU was measured with just the sink running, no source device initialized just to be sure. I hope I don't have to switch to gr-iio instead and write code specifically for each device.

kantooon commented 4 years ago

So, I did a little more digging around. This info is for other people using this like me from GNU radio via gr-osmosdr and Soapy. GNU radio doesn't have a type of gr_complex\<int16>, only gr_complex\<float>. There is no way to specify a different format (CS16) in the source parameters. This is what the sink code does: https://github.com/osmocom/gr-osmosdr/blob/4d83c6067f059b0c5015c3f59f8117bbd361e877/lib/soapy/soapy_sink_c.cc#L72 Now, the float to short int conversion and scaling... Yes this would add overhead. Is it normal that a full blown interpolating resampler in GNU radio takes less CPU time than this conversion? I'm still not very convinced, but this issue is quite minor as it doesn't affect the functonality.

zuckschwerdt commented 4 years ago

There is overhead with the conversion, but on a typical computer this shouldn't be noticeable that much. Wild guess, it could be an adverse situation with our spin locks. If there is no way to pinpoint the issue with other setups (formats, etc…) then profiling (e.g. instrumenting with Gperftools) would be the next step.

kantooon commented 4 years ago

Seems related to the tx_streamer buffer size. Funny enough, I set this myself to 4096 back in the day (who needs more than 640k right?). By increasing it to 2^18, CPU time drops to half at 1 Msps. The rx_streamer sets the buffer size by sample rate. Should the tx_streamer do the same? Up for discussion.

kantooon commented 4 years ago

This is my offending commit: https://github.com/pothosware/SoapyPlutoSDR/commit/0db661d4bf15bc285cf6acd2cf388d8bea3b4db9 Lots have changed in the code base since then, and I don't know the code so well anymore.

zuckschwerdt commented 4 years ago

Sounds like a typical USB issue. Bigger buffers will stream better. But the tx_streamer needs to provide a resonable latency, thus the smal IIO buffer. Does the gr-osmosdr code respect the MTU? Best case is to chunk exactly MTU sized. Ah, well I guess we don't announce our TX MTU. Can you change the 0 to 4096 on https://github.com/pothosware/SoapyPlutoSDR/blob/master/PlutoSDR_Streaming.cpp#L163 and see if that changes anything?

kantooon commented 4 years ago

Yes, agreed, we need to keep the latency in check as well. Anyway, I'm still not happy with the performance, I got sidetracked into Analog's libiio and Pluto has it's own Zynq, IMHO this type conversion should be happening on the Zynq...

zuckschwerdt commented 4 years ago

Soapy is fine to run on the Pluto (I do that and on top consumers like rtl_433). But then you would use e.g. SoapyRemote and not IIO. IIO has no channel conversion (for transport).

zuckschwerdt commented 4 years ago

…I added CS12 and CS8 for that reason (USB bandwidth limit). "Use CS12 for 8 Msps (and lower) over SoapyRemote. Use CS8 with SoapyRemote for 10 Msps." s.a. #19

zuckschwerdt commented 4 years ago

Please reopen if there is an idea how to improve things.