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


von Tastkopf (Gast)


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.
1
byte[] buffer = new byte[102400];
2
      int recLen = 0;
3
4
      try
5
      {
6
        long start = new Date().getTime();
7
        while (recLen < 10*1024*1024)
8
        {
9
          len = LibusbJava1.libusb_bulk_transfer(handle, (byte) 0x81, buffer, 102400, 1000);
10
          recLen += len;
11
        }
12
        long duration = new Date().getTime() - start;
13
        System.out.println(duration + "ms");
14
        System.out.println(((float)10*1000/(float)duration) + "MByte/s");
15
      }
16
      catch (LibusbError e)
17
      {
18
        e.printStackTrace();
19
      }

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

von Christian R. (supachris)


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.

von Tastkopf (Gast)


Lesenswert?

Mit Einbusen hatte ich gerechnet, aber das der Unterschied so extrem 
sein könnte hatte ich nicht erwartet.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.