Relatively simple flow-graph, not complete yet by any stretch of the imagination.

It starts out innocuous enough, but really gets going after a while. The RSS grows by about 150M/minute, the Virtual Size at a somewhat slower pace. After a few minutes of running, its RSS has grown enough that it's consuming *most* of the physical memory on the system, and the kernel is starting to look for solutions to the problem, the virtual size grows to about 6.2Gbyte on my system before things get utterly unusable, and I have to go to the console and kill it off. If I reduce the bandwidth, it grows more slowly, but it still grows, and grows,
  and grows, and grows.

I was even well-behaved in my FFT size--4096 bins, which is a nice even multiple of the page-size and everything.

The Gnu Radio memory behaviour is really starting to bug me. A lot. So much so that I'm contemplating going directly from UHD to my application (in this case, a multi-channel riometer). I really don't want to do that. If I had the time to dedicate to it, and the required depth of knowledge of the scheduler guts, I'd fix it myself, and post patches. I understand that the memory tricks are stream-performance "optimizations", but it's rather unoptimal when your system is eaten alive by stuff that, at least given a superficial glance, should be fairly innocuous (except, perhaps for the 25Msps bit, which nobody would argue is "casual" by any measure).

--
Marcus Leech
Principal Investigator
Shirleys Bay Radio Astronomy Consortium
http://www.sbrac.org

Attachment: untitled.grc
Description: application/gnuradio-grc

#!/usr/bin/env python
##################################################
# Gnuradio Python Flow Graph
# Title: Top Block
# Generated: Tue Jul  5 20:43:40 2011
##################################################

from gnuradio import eng_notation
from gnuradio import gr
from gnuradio import uhd
from gnuradio import window
from gnuradio.eng_option import eng_option
from gnuradio.gr import firdes
from gnuradio.wxgui import fftsink2
from grc_gnuradio import wxgui as grc_wxgui
from optparse import OptionParser
import wx

class top_block(grc_wxgui.top_block_gui):

	def __init__(self):
		grc_wxgui.top_block_gui.__init__(self, title="Top Block")
		_icon_path = "/usr/share/icons/hicolor/32x32/apps/gnuradio-grc.png"
		self.SetIcon(wx.Icon(_icon_path, wx.BITMAP_TYPE_ANY))

		##################################################
		# Variables
		##################################################
		self.tprate = tprate = 500
		self.samp_rate = samp_rate = 100e6/4
		self.freq = freq = 37.0e6
		self.fftsize = fftsize = 2048
		self.fftdecim = fftdecim = 3

		##################################################
		# Blocks
		##################################################
		self.Main = self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
		self.Main.AddPage(grc_wxgui.Panel(self.Main), "Spectral")
		self.Main.AddPage(grc_wxgui.Panel(self.Main), "Power")
		self.Add(self.Main)
		self.wxgui_fftsink2_0 = fftsink2.fft_sink_c(
			self.Main.GetPage(0).GetWin(),
			baseband_freq=freq,
			y_per_div=10,
			y_divs=10,
			ref_level=50,
			ref_scale=2.0,
			sample_rate=samp_rate,
			fft_size=1024,
			fft_rate=5,
			average=True,
			avg_alpha=0.250,
			title="FFT Plot",
			peak_hold=False,
		)
		self.Main.GetPage(0).Add(self.wxgui_fftsink2_0.win)
		self.uhd_usrp_source_0 = uhd.usrp_source(
			device_addr="addr=192.168.10.2",
			io_type=uhd.io_type.COMPLEX_FLOAT32,
			num_channels=1,
		)
		self.uhd_usrp_source_0.set_samp_rate(samp_rate)
		self.uhd_usrp_source_0.set_center_freq(freq, 0)
		self.uhd_usrp_source_0.set_gain(0, 0)
		self.gr_vector_sink_x_0 = gr.vector_sink_f(fftsize)
		self.gr_stream_to_vector_0 = gr.stream_to_vector(gr.sizeof_gr_complex*1, fftsize)
		self.gr_single_pole_iir_filter_xx_0 = gr.single_pole_iir_filter_ff((1.0/((samp_rate/fftsize)/tprate)/2)*fftdecim, fftsize)
		self.gr_null_sink_0 = gr.null_sink(gr.sizeof_float*fftsize)
		self.gr_keep_one_in_n_1 = gr.keep_one_in_n(gr.sizeof_gr_complex*fftsize, fftdecim)
		self.gr_keep_one_in_n_0 = gr.keep_one_in_n(gr.sizeof_float*fftsize, int(samp_rate/fftsize)/tprate/fftdecim)
		self.gr_fft_vxx_0 = gr.fft_vcc(fftsize, True, (window.blackmanharris(1024)), True)
		self.gr_complex_to_mag_0 = gr.complex_to_mag(fftsize)

		##################################################
		# Connections
		##################################################
		self.connect((self.gr_keep_one_in_n_0, 0), (self.gr_null_sink_0, 0))
		self.connect((self.gr_single_pole_iir_filter_xx_0, 0), (self.gr_keep_one_in_n_0, 0))
		self.connect((self.gr_fft_vxx_0, 0), (self.gr_complex_to_mag_0, 0))
		self.connect((self.gr_complex_to_mag_0, 0), (self.gr_single_pole_iir_filter_xx_0, 0))
		self.connect((self.uhd_usrp_source_0, 0), (self.gr_stream_to_vector_0, 0))
		self.connect((self.uhd_usrp_source_0, 0), (self.wxgui_fftsink2_0, 0))
		self.connect((self.gr_stream_to_vector_0, 0), (self.gr_keep_one_in_n_1, 0))
		self.connect((self.gr_keep_one_in_n_1, 0), (self.gr_fft_vxx_0, 0))
		self.connect((self.gr_keep_one_in_n_0, 0), (self.gr_vector_sink_x_0, 0))

	def get_tprate(self):
		return self.tprate

	def set_tprate(self, tprate):
		self.tprate = tprate
		self.gr_keep_one_in_n_0.set_n(int(self.samp_rate/self.fftsize)/self.tprate/self.fftdecim)
		self.gr_single_pole_iir_filter_xx_0.set_taps((1.0/((self.samp_rate/self.fftsize)/self.tprate)/2)*self.fftdecim)

	def get_samp_rate(self):
		return self.samp_rate

	def set_samp_rate(self, samp_rate):
		self.samp_rate = samp_rate
		self.wxgui_fftsink2_0.set_sample_rate(self.samp_rate)
		self.uhd_usrp_source_0.set_samp_rate(self.samp_rate)
		self.gr_keep_one_in_n_0.set_n(int(self.samp_rate/self.fftsize)/self.tprate/self.fftdecim)
		self.gr_single_pole_iir_filter_xx_0.set_taps((1.0/((self.samp_rate/self.fftsize)/self.tprate)/2)*self.fftdecim)

	def get_freq(self):
		return self.freq

	def set_freq(self, freq):
		self.freq = freq
		self.wxgui_fftsink2_0.set_baseband_freq(self.freq)
		self.uhd_usrp_source_0.set_center_freq(self.freq, 0)

	def get_fftsize(self):
		return self.fftsize

	def set_fftsize(self, fftsize):
		self.fftsize = fftsize
		self.gr_keep_one_in_n_0.set_n(int(self.samp_rate/self.fftsize)/self.tprate/self.fftdecim)
		self.gr_single_pole_iir_filter_xx_0.set_taps((1.0/((self.samp_rate/self.fftsize)/self.tprate)/2)*self.fftdecim)

	def get_fftdecim(self):
		return self.fftdecim

	def set_fftdecim(self, fftdecim):
		self.fftdecim = fftdecim
		self.gr_keep_one_in_n_1.set_n(self.fftdecim)
		self.gr_keep_one_in_n_0.set_n(int(self.samp_rate/self.fftsize)/self.tprate/self.fftdecim)
		self.gr_single_pole_iir_filter_xx_0.set_taps((1.0/((self.samp_rate/self.fftsize)/self.tprate)/2)*self.fftdecim)

if __name__ == '__main__':
	parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
	(options, args) = parser.parse_args()
	tb = top_block()
	tb.Run(True)

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

Reply via email to