Author Topic: libusb winusb speed differences  (Read 20458 times)

mediumrare

  • Member
  • ***
  • Posts: 4
libusb winusb speed differences
« on: May 09, 2012, 06:40:23 pm »
Hello,
I am writing an app that will transfer data (up to 3GBytes filesize) from a linux embedded device over USB to the PC. (C# .NET)
My data transfer rates are much lower than the usb 2.0 specification.
From what I can ascertain doing speed tests with console applications(open device, read while there is something in the pipe), the libusb transfer rate is ~10 times faster than winusb, though that is still only 1MByte/second.
Does anybody know of any documentation on transfer rates using these libraries.
The libusb seems to be transferring about 2048Bytes/ms whereas winusb seems to have an ~11ms between every second packet -see logging extract
nr = 2048   10:35:52.975
nr = 2048   10:35:52.987
nr = 2048   10:35:52.988
nr = 2048   10:35:52.999
nr = 2048   10:35:52.999
nr = 2048   10:35:53.010
nr = 2048   10:35:53.011
nr = 2048   10:35:53.021

At the linux end I am just doing a hexdump of the file out the usb port.

Can anyone shed any light on why this is so - what might the delay be and why don't I see this with libusb?
Thank you to any respondants in advance.
Regards

Tsuneo

  • Frequent Contributor
  • ****
  • Posts: 145
Re: libusb winusb speed differences
« Reply #1 on: May 09, 2012, 10:34:59 pm »
Test it with much greater transfer size, more than mega bytes.

PC host controller delays transfer completion interrupt until next SOF of micro-frame. In this way, the next transfer always starts at next micro-frame, when your PC application repeats transfers synchronously. That is, the transfer speed is proportional to the transfer size, until it saturates the bus bandwidth.

Quote
whereas winusb seems to have an ~11ms between every second packet
Sound like you are seeing thread switch quantum, instead of transfer speed.
Is it synchronous (non-OVERLAPPED) call?

For WinUSB, apply RAW_IO policy to the bulk IN pipe. And put a couple of OVERLAPPED WinUsb_ReadPipe calls in advance. And then, these calls are stored on the host controller queue, directly, which results in seamless transfer sequence.

Tsuneo
« Last Edit: May 09, 2012, 10:48:56 pm by Tsuneo »

mediumrare

  • Member
  • ***
  • Posts: 4
Re: libusb winusb speed differences
« Reply #2 on: May 10, 2012, 12:05:27 am »
Thank you.
I have tried to make the application as thread-free as possible. Here is my code:
Quote
class Program
    {
        public static USBInterface ifc;
        public const string deviceGuid = "8A99B4FA-4942-4286-B464-3D92EF91D0AC";
        public bool opened = false;
        const int UsbReadBufferSize = 8192;

        public static void Main(string[] args)
        {
            if (ifc != null) throw new InvalidOperationException("Already open");
            USBDeviceInfo[] devices = USBDevice.GetDevices(deviceGuid);
            USBDevice device = null;
            bool firstTimeIn = true;
           

            if (devices.Length > 0)
            {
                Console.WriteLine("Found device");
                device = new USBDevice(devices[0].DevicePath);
                ifc = device.Interfaces[1];
                ifc.InPipe.Policy.RawIO = true;
            }
            else
            {
                Console.WriteLine("No devices found");

            }

            byte[] buffer = new byte[UsbReadBufferSize];
            int nread;
            while (ifc != null)
            {
                //nread = ifc.InPipe.Read(buffer, 0, UsbReadBufferSize);
                nread = ifc.InPipe.Read(buffer);
                Console.WriteLine("nr = " + nread.ToString() + "   " + DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture));
                if (nread > 0)
                {
                    if (firstTimeIn)
                    {
                        Console.WriteLine("Start=" + DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture));
                        firstTimeIn = false;
                    }
                    if (nread == 2)
                    {
                        Console.WriteLine("Finish=" + DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture));
                        firstTimeIn = true;
                    }
                }
            }
        }
    }

I am not even copying the data from the buffer. Whether or not I put DateTime out every read or not makes no difference to the transfer rate. The last packet is 2 bytes long. I have added your suggestion regarding RAW_IO. However I don't understand what you are suggesting about adding OVERLAPPED ReadPipe calls in advance.... Could you explain this a bit more please?
Thank you

Tsuneo

  • Frequent Contributor
  • ****
  • Posts: 145
Re: libusb winusb speed differences
« Reply #3 on: May 10, 2012, 01:07:50 am »
DateTime have the resolution of just quantum tick.
Use System.Diagnostics.Stopwatch Class, which applies QueryPerformanceCounter() internally.
Enclose the target routine call with StopWatch.Start and StopWatch.Stop
StopWatch.Elapsed gives the time between Start/Stop

Code: [Select]
Stopwatch stopWatch = new Stopwatch();
while (ifc != null)
{
    stopWatch.Start();
    nread = ifc.InPipe.Read(buffer);
    stopWatch.Stop();
    Console.WriteLine( stopWatch.Elapsed.TotalMilliseconds );
    ...

Tsuneo

mediumrare

  • Member
  • ***
  • Posts: 4
Re: libusb winusb speed differences
« Reply #4 on: May 10, 2012, 04:32:17 pm »
Thank you for this suggestion - but I have already tried the stopwatch. I tried it again with your exact suggestion and elapsed time was 16003.7622 for a 2.9MB file.

What are the overlapped read calls you suggested?

Also I know you stated that the bigger the filesize->the faster the transfer rate, but even considering this the above transfer rate is very low for what is these days a very small file.

mediumrare

  • Member
  • ***
  • Posts: 4
Re: libusb winusb speed differences
« Reply #5 on: May 13, 2012, 06:53:59 pm »
It emerges that the linux command hexdump was the bottleneck, not the usb drivers. Thank you for all your help.