www.mikrocontroller.net

Forum: PC-Programmierung Libusb-1.0, Übertragungsrate optimieren


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Tastkopf (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,

Erstmal kurz zu meinem Aufbau, ich hab ein USB Device (EFM32 
Microcontroller mit integriertem Full-Speed USB Controller). Dieses 
Device sendet einfach nur Daten so schnell es kann (while-Schleife um 
die Sende-Funktion). Verwendet wird ein Bulk-Transfer welcher 
theoretisch 1,24MByte/s erreichen könnte (laut USB Spec).

Für einen ersten Test der tatsächlich erreichbaren Netto-Datenrate, habe 
ich mir ein kleines C# Programm geschrieben welches einen Virtuellen 
COM-Port öffnen kann und die Datenrate der eingehenden Daten ermittelt. 
Damit kam ich auf ca. 1,2MByte/s, also ziemlich nah am theoretischen 
Maximum.

Nun wollte ich das Ganze mittels libusb unter Java testen. Dafür kommt 
die LibusbJava (ein Javawrapper umd die libusb-1.0 unter Java verwenden 
zu können) zum Einsatz und als Treiber die libusb-1.0 für Windows ( 
http://libusb.org/wiki/windows_backend# ).
Auch hier hab ich mir wieder nur ein kleines Programm geschrieben 
welches nur der Geschwindigkeitsmessung dient, jedoch ist 
Geschwindigkeit sehr stark von der Buffergröße abhängig, welche ich dir 
Bulktranfer-Funktion übergebe.
Es werden immer 10MByte empfangen, unabhängig von Buffergröße.
Umgebung ist ein Dual-Core PC mit Windows 7 64bit.
byte[] buffer = new byte[102400];
      int recLen = 0;

      try
      {
        long start = new Date().getTime();
        while (recLen < 10*1024*1024)
        {
          len = LibusbJava1.libusb_bulk_transfer(handle, (byte) 0x81, buffer, 102400, 1000);
          recLen += len;
        }
        long duration = new Date().getTime() - start;
        System.out.println(duration + "ms");
        System.out.println(((float)10*1000/(float)duration) + "MByte/s");
      }
      catch (LibusbError e)
      {
        e.printStackTrace();
      }

Bei einer Bufferlenght von 102400 Byte komme ich auf 0,95MByte/s
bei 10240 sind es noch 0.87MByte/s
bei 1024 sind es 0.48MByte/s
bei 64 Byte sogar nur 0,03MByte/s


Da ein USB-Transfer auf 64Byte Paketen beruht (bei Full-Speed USB + Bulk 
Tranfer), sollte die Datenrate doch relativ konstant sein solang die 
Buffergröße ein vielfaches von 64Byte ist. Mit Schwankungen von 100% 
hätte ich gerechnet, aber die Schankungen von weit über 1000% haben mich 
doch etwas schockiert.
Habt ihr ähnliche Erfahrungen gemacht? Ich kann mir nicht so ganz 
vorstellen das die Libusb Implementierung derart ineffizient ist, wo 
könnte eurer Meinung nach das Problem liegen?

Grüße
Chris

Autor: Christian R. (supachris)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Tastkopf schrieb:
> Ich kann mir nicht so ganz
> vorstellen das die Libusb Implementierung derart ineffizient ist, wo
> könnte eurer Meinung nach das Problem liegen?

Ist nicht ineffizient sondern das ist systembedingt. Durch so kleine 
Anforderungen muss der Treiber ständig Traffic zum Gerät erzeugen und 
die Mini-Pakete durch alle Treiber-Schichten und Callbacks bis zur 
Anwendung durchreichen. Das kostst massiv Zeit. Ist bei jeder anderen 
Schnittstelle genau so. Wir arbeiten mit WinUSB und auch da bekommt man 
nur sinnvolle Geschwindigkeiten wenn man große Datenmengen mit einem Mal 
anfordert. Und richtig schnell wirds erst asynchron mit mehereren 
Anfragen in der Warteschlange.

Autor: Tastkopf (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Mit Einbusen hatte ich gerechnet, aber das der Unterschied so extrem 
sein könnte hatte ich nicht erwartet.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net