Re: [Discuss-gnuradio] New implementation for fusb_linux without allocs/frees

2009-02-23 Thread Johnathan Corgan
On Sun, Feb 22, 2009 at 10:38 PM, Stefan Bruens
stefan.bru...@rwth-aachen.de wrote:

 attached is a new version for fusb_linux.cc.

Stefan--THANKS for all the wonderful work you've been submitting; we
really appreciate the kinds of optimization work you are doing.  We
will likely get all of it into our distribution.

However, it makes it easier for us to review and apply your work if
you follow the guidelines in the below Wiki page:

http://gnuradio.org/trac/wiki/PatchSubmissionGuidelines

Thanks,

Johnathan


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


Re: [Discuss-gnuradio] New implementation for fusb_linux without allocs/frees

2009-02-23 Thread Eric Blossom
On Mon, Feb 23, 2009 at 07:38:14AM +0100, Stefan Bruens wrote:
 Hi,
 
 attached is a new version for fusb_linux.cc.
 
 The current implementation uses three std::list lists for free, pending and 
 completed urbs, so submitting a single urb causes three allocs and three 
 frees 
 (pushing and popping of the list).
 
 The new implementation uses a circular list for the urbs, where each urb is 
 marked as free, pending or completed. As the total number of allocated urbs 
 is 
 constant, no allocs or frees are needed.
 
 Benchmark:
 usrp/host/apps/test_usrp_standard_tx -B 512 -N 64 -M 128
 
 old code needs ~990e6 instructions, new code 690e6 instructions. The call to 
 usrp_basic_tx::write goes down from 380e6 to 80e6 (so almost down to a fifth 
 ...), the remaining instructions is the pattern fill for the sample buffer.
 
 Regards,
 Stefan

Thanks!

Stefan, please tell me again how you measured the instruction count?

Also, if you haven't already, please send in the form that starts the
copyright assignment.  Contact me off-list if you've got any more
questions about that.

Eric


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


[Discuss-gnuradio] New implementation for fusb_linux without allocs/frees

2009-02-22 Thread Stefan Bruens
Hi,

attached is a new version for fusb_linux.cc.

The current implementation uses three std::list lists for free, pending and 
completed urbs, so submitting a single urb causes three allocs and three frees 
(pushing and popping of the list).

The new implementation uses a circular list for the urbs, where each urb is 
marked as free, pending or completed. As the total number of allocated urbs is 
constant, no allocs or frees are needed.

Benchmark:
usrp/host/apps/test_usrp_standard_tx -B 512 -N 64 -M 128

old code needs ~990e6 instructions, new code 690e6 instructions. The call to 
usrp_basic_tx::write goes down from 380e6 to 80e6 (so almost down to a fifth 
...), the remaining instructions is the pattern fill for the sample buffer.

Regards,

Stefan
 
-- 
Stefan Brüns  /  Bergstraße 21  /  52062 Aachen
phone: +49 241 53809034 mobile: +49 151 50412019
/* -*- c++ -*- */
/*
 * Copyright 2003 Free Software Foundation, Inc.
 * 
 * This file is part of GNU Radio
 * 
 * GNU Radio is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 * 
 * GNU Radio is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with GNU Radio; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
#include config.h
#endif

#include fusb_linux_2.h
#include usb.h		// libusb header
#include stdexcept
#ifdef HAVE_LINUX_COMPILER_H
#include linux/compiler.h
#endif
#include linux/usbdevice_fs.h	// interface to kernel portion of user mode usb driver
#include sys/ioctl.h
#include assert.h
#include string.h
#include algorithm
#include errno.h
#include string.h
#include iostream

#define MINIMIZE_TX_BUFFERING 1		// must be defined to 0 or 1


static const int MAX_BLOCK_SIZE = fusb_sysconfig::max_block_size();		// hard limit
static const int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE;
static const int DEFAULT_BUFFER_SIZE = 4 * (1L  20);// 4 MB / endpoint

enum urb_state_t { FREE, PENDING, COMPLETED };
struct _urb_private_data {
fusb_ephandle_linux* handle;
	enum urb_state_t state;
	// int count readers;
};


// Totally evil and fragile extraction of file descriptor from
// guts of libusb.  They don't install usbi.h, which is what we'd need
// to do this nicely.
//
// FIXME if everything breaks someday in the future, look here...

static int
fd_from_usb_dev_handle (usb_dev_handle *udh)
{
  return *((int *) udh);
}

inline static void
urb_set_ephandle (usbdevfs_urb *urb, fusb_ephandle_linux *handle)
{
  ((_urb_private_data*)(urb-usercontext))-handle = handle;
}

inline static fusb_ephandle_linux *
urb_get_ephandle (usbdevfs_urb *urb)
{
  return ((_urb_private_data*)(urb-usercontext))-handle;
}

// 
// 		   USB request block (urb) allocation
// 

static usbdevfs_urb *
alloc_urb (fusb_ephandle_linux *self, int buffer_length, int endpoint,
	   bool input_p, unsigned char *write_buffer)
{
  usbdevfs_urb	*urb = new usbdevfs_urb;
  memset (urb, 0, sizeof (*urb));

  urb-buffer_length = buffer_length;

  // We allocate dedicated memory only for input buffers.
  // For output buffers we reuse the same buffer (the kernel 
  // copies the data at submital time)

  if (input_p)
urb-buffer = new unsigned char [buffer_length];
  else
urb-buffer = write_buffer;

  // init common values

  urb-type = USBDEVFS_URB_TYPE_BULK;
  urb-endpoint = (endpoint  0x7f) | (input_p ? 0x80 : 0);

  // USBDEVFS_URB_QUEUE_BULK goes away in linux 2.5, but is needed if
  // we are using a 2.4 usb-uhci host controller driver.  This is
  // unlikely since we're almost always going to be plugged into a
  // high speed host controller (ehci)
#if 0  defined (USBDEVFS_URB_QUEUE_BULK)
  urb-flags = USBDEVFS_URB_QUEUE_BULK;
#endif

  urb-signr = 0;
  urb-usercontext = new _urb_private_data;
  ((_urb_private_data*)urb-usercontext)-state=FREE;
  urb_set_ephandle (urb, self);

  return urb;
}

static void
free_urb (usbdevfs_urb *urb)
{
  // if this was an input urb, free the buffer
  if (urb-endpoint  0x80)
delete [] ((unsigned char *) urb-buffer);

  delete (_urb_private_data*)(urb-usercontext);
  delete urb;
}

// 
// device handle
// 


fusb_devhandle_linux::fusb_devhandle_linux (usb_dev_handle *udh)
  : fusb_devhandle (udh)
{
  // that's all
}