Saturday, 3 May 2014

Raspberry Pi USB 2.0 'Gigabit' Ethernet Adapter throughput test

 

Update (2015-02): RaspBerry Pi Generation 2 model B - Since this USB 2.0 'Gigabit' Ethernet adapter throughput was performance bound by low CPU there should be some improvement with this new board. One can only hope that it would be closer to the Banana Pi performance with the same adapter of 39.5 MB/s (download) and 19.7 MB/s (upload) instead of RPi B non-overclocked performance of 12.5 MB/s (download) and 12.3 MB/s (upload). I would need a new RPi2B board to do tests, but worst case its performance should (still) be better than the builtin 10/100 NIC. In fact thinking about it a bit more because of the 5 port USB hub internal to the RPi2B, its performance will not be as high as the Banana Pi with dedicated USB 2.0 ports. So in theory it should be slower than the Banana Pi, but faster than a RPi B/B+ at transferring data.

Update (2014-07): There is a new RPi model B+ with 4 USB ports (well 5 in fact when you include ethernet using a LAN9514 chip instead of 3 ports using the LAN9512 in the model B). Just to be clear the tests below were done on the model B. If and when I repeat the the tests with a model B+ I do not expect to see better performance.

Raspberry Pi USB 2.0 'Gigabit' Ethernet Adapter throughput test

I bought a cheap USB 2.0 to Gigabit Ethernet Adapter (Maximum Data Transfer Rate 480 Mbps according to the website), mostly because I wanted to see how it performed on a Raspberry Pi. It can never reach 480Mbps, but it will be interesting to see how much throughput it can achieve.

As usual, I have censored any identifying information about my local network or personal hardware.

Hardware Configuration:

Raspberry Pi model B - 512MB model, 128MB of RAM allocated to GPU, no overclocking
Inbuilt 10/100 NIC is not connected.
Top USB port is empty
Bottom USB port has USB 2.0 to Gigabit Ethernet Adapter plugged in and plugged.into router





      
+---+  +------+         +------+           +----------------+
|RPi|->|USB2.0|->1Gbps->|router|->200Mbps->|Remote webserver|
+---+  +------+ Ethernet+------+ Internet  +----------------+
      
480Mibps             |
                         1Gbps Ethernet
                            |
                            v
                     +-------------+
                     |LAN webserver|
                     +-------------+


Software Configuration: 

I had to add in an extra two lines for this new USB eth1 NIC to get it working on the Raspberry Pi, the last two lines below.

pi@raspberrypi ~ $ cat /etc/network/interfaces
auto lo

iface lo inet loopback

iface eth0 inet dhcp

allow-hotplug wlan0

iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

allow-hotplug eth1

iface eth1 inet dhcp
pi@raspberrypi ~ $

pi@raspberrypi ~ $ lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/3p, 480M
        |__ Port 1: Dev 3, If 0, Class=vend., Driver=smsc95xx, 480M
        |__ Port 3: Dev 4, If 0, Class=vend., Driver=smsc75xx, 480M

pi@raspberrypi ~ $ sudo ethtool eth1
Settings for eth1:
        Supported ports: [ TP MII ]
        Supported link modes:   10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Half 1000baseT/Full
        Supported pause frame use: No
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full
                                100baseT/Half 100baseT/Full
                                1000baseT/Full
        Advertised pause frame use: Symmetric Receive-only
        Advertised auto-negotiation: Yes
        Link partner advertised link modes:  10baseT/Half 10baseT/Full
                                             100baseT/Half 100baseT/Full
                                             1000baseT/Half 1000baseT/Full
        Link partner advertised pause frame use: Symmetric Receive-only
        Link partner advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full

        Port: MII
        PHYAD: 1
        Transceiver: internal
        Auto-negotiation: on
        Supports Wake-on: pumbag
        Wake-on: d
        Current message level: 0x00000007 (7)
                               drv probe link
        Link detected: yes
pi@raspberrypi ~ $  netstat -i
Kernel Interface table
Iface   MTU Met   RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0       1500 0         0      0      0 0             0      0      0      0 BMU
eth1       1500 0       377      0      0 0           382      0      0      0 BMRU
lo        65536 0        14      0      0 0            14      0      0      0 LRU

pi@raspberrypi ~ $ ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 80:3f:5d:**:**:**
          inet addr:*.*.*.*  Bcast:*.*.*.*  Mask:*.*.*.*
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:385 errors:0 dropped:0 overruns:0 frame:0
          TX packets:390 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:29012 (28.3 KiB)  TX bytes:50254 (49.0 KiB)

pi@raspberrypi ~ $


Internet Test (via a 200Mbit/sec broadband connection)


Download a single 100MiB file to the Pi through the USB 2.0 Gigabit Ethernet Adapter and send the downloaded data to /dev/null.

pi@raspberrypi ~$ time time wget http://qrng.physik.hu-berlin.de/files/speedtest-100MB.bin -O /dev/null
time wget http://qrng.physik.hu-berlin.de/files/speedtest-100MB.bin -O /dev/null
--2014-05-04 01:06:23--  http://qrng.physik.hu-berlin.de/files/speedtest-100MB.bin
Resolving qrng.physik.hu-berlin.de (qrng.physik.hu-berlin.de)... 141.20.41.134
Connecting to qrng.physik.hu-berlin.de (qrng.physik.hu-berlin.de)|141.20.41.134|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: `/dev/null'

100%[=====================================================================>] 104,857,600 1.07M/s   in 2m 26s

2014-05-04 01:08:49 (701 KB/s) - `/dev/null' saved [104857600/104857600]


real    2m26.290s
user    0m0.880s
sys     0m3.130s
pi@raspberrypi ~ $


LAN Test

Download a single 100MiB file to the Pi through USB 2.0 Gigabit Ethernet Adapter and send the downloaded data to /dev/null. The data source is on the Local network from a machine with a 1 Gbit/sec NIC patched directly into the router with the data being read from a RAM disk to maximise read speed.
root@webserver:~# apt-get install nginx nginx-common nginx-full
root@webserver:~# /usr/sbin/nginx &
root@webserver:~# mkdir /usr/share/nginx/www/ramdisk
root@webserver:~# chmod 777 /usr/share/nginx/www/ramdisk
root@webserver:~# free -m
root@webserver:~# mount -t tmpfs -o size=256M tmpfs /usr/share/nginx/www/ramdisk
root@webserver:~# cp speedtest-100MB.bin /usr/share/nginx/www/ramdisk


pi@raspberrypi ~$  time wget http://*.*.*.*/ramdisk/speedtest-100MB.bin -O /dev/null
--2014-05-04 01:17:24--  http://*.*.*.*/ramdisk/speedtest-100MB.bin
Connecting to *.*.*.*:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: `/dev/null'

100%[=====================================================================>] 104,857,600 12.6M/s   in 8.0s

2014-05-04 01:17:32 (12.5 MB/s) - `/dev/null' saved [104857600/104857600]


real    0m8.049s
user    0m0.600s
sys     0m2.310s

pi@raspberrypi ~ $


Results
Peak Internet transfer rate 1.07MiB/sec (8.98Mbps) - about 13 hops away
Average Internet throughput 701KiB/sec - about 13 hops away.

Because this server is so many hops away it's throughput varies wildly with time of day and is effected by so  many uncontrolled fluctuations on every hop in between. This result is more an example of a typical Internet based throughput than a maximum throughput.







Peak LAN transfer rate 12.6 MiB/sec (105.7Mbps) - for 1000Mbps (even limited to USB 2.0 480Mbps) this is not a very good throughput.
Average LAN throughput 12.5 MiB/sec - for 1000Mbps (even limited to USB 2.0 480Mbps) this is not a very good throughput.

I'm not very pleased with the USB 2.0 Gigabit Ethernet Adapter result for the Raspberry Pi. I was expecting a result somewhere between 20 MiB/sec and 40 MiB/sec. I tried to enable jumbo frames ("sudo ifconfig eth1 mtu 9000") on the webserver and on the Raspberry Pi to see if I could get a better result, but I couldn't get it to work. I'm not quite sure why, yet but I'm still looking into it.

Additional testing

I decided to try the test in reverse. Install a webserver on the Raspberry P, and make a 128MiB ramdisk to download a file from the Raspberry Pi through USB 2.0, through the USB 2.0 Gigabit Ethernet Adapter down to the midrange PC with a Gigabit NIC, and then throw the data away.
pi@raspberrypi ~ $ sudo apt-get install nginx
pi@raspberrypi ~ $ sudo mkdir /usr/share/nginx/www/ramdisk 
pi@raspberrypi ~ $ sudo chmod 777 /usr/share/nginx/www/ramdisk
pi@raspberrypi ~ $ free -m 
pi@raspberrypi ~ $ sudo mount -t tmpfs -o size=128M tmpfs /usr/share/nginx/www/ramdisk
pi@raspberrypi ~ $  sudo cp speedtest-100MB.bin /usr/share/nginx/www/ramdisk

midrangepc $ time wget http://*.*.*.*/ramdisk/speedtest-100MB.bin -O /dev/null
--2014-05-04 17:56:38--  http://*.*.*.*/ramdisk/speedtest-100MB.bin
Connecting to *.*.*.*:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: `/dev/null'

100%[======================================>] 104,857,600 12.3M/s   in 7.8s

2014-05-04 17:56:46 (12.2 MB/s) - `/dev/null' saved [104857600/104857600]


real    0m7.819s
user    0m0.392s
sys     0m1.744s
midrangepc $


No better than before, slightly less, same general transfer rate. But I did notice one thing, that the CPU load on the Raspberry Pi hit the roof during the transfer, so I overclocked it from 700 to 1000 MHz ("sudo raspi-config") and ran the exact same test again.

midrangepc $ time wget http://*.*.*.*/ramdisk/speedtest-100MB.bin -O /dev/null
--2014-05-04 18:06:22--  http://*.*.*.*/ramdisk/speedtest-100MB.bin
Connecting to *.*.*.*:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: `/dev/null'

100%[======================================>] 104,857,600 17.0M/s   in 6.1s

2014-05-04 18:06:28 (16.4 MB/s) - `/dev/null' saved [104857600/104857600]


real    0m6.094s
user    0m0.312s
sys     0m1.588s
midrangepc$


Faster, so empirically it looks like there is not enough CPU grunt in the RPi to saturate this hardware to it's maximum throughput potential. Maybe the smsc75xx driver on the RPi which pushes data to the Microchip's LAN7500 Hi-Speed USB 2.0 to 10/100/1000 Ethernet Controller chip, is CPU bound and needs to be optimised for the ARM architecture. Or maybe this is just as good as it gets on the RPi, that it is already fully optimised.

I have searched the web and some people are seeing throughput of 38.2MB/sec (305.6Mibps) using a MacBook Air using the same USB 2.0 Gigabit Ethernet Adapter. Browsing through the latest Linux kernel log file for updates to smsc75xx there was a patch for jumbo frames, which may not be in the RPi kernel yet, which could explain my problems trying to use jumbo frames above. Reading through the source code for the smsc75xx.c driver is giving me a headache, so I think that I will just accept the probable fact that this hardware does not perform all that well on a RPi. And it appears to be CPU bound.

Update (Nov 2014): I ran the above tests on a Banana Pi and managed to achieve 39.5 MB/s (download) and 19.7 MB/s (upload). But it is not really required, since the Banana Pi has a builtin 10/100/1000Mbps NIC that I have tested that can download at 109 MB/sec (872Mbps) and upload data at 71.5 MB/s (572Mbps).

9 comments:

  1. Have you tried Banana Pi 10/100/1000 port?
    I would like to see its results.

    ReplyDelete
    Replies
    1. Sorry but I don't have one, I would test if i did. The CPU in a Banana Pi is a Allwinner dual core A20 A7-Cortex (contracts and NDA's needed for access to any documentation). Most ARM CPU's that say gigabit mean that it can connect to a gigabit switch, but not necessarily be able to saturate the link with that much data read this:
      http://www.raspberrypi.org/forums/viewtopic.php?p=397285&sid=71fbe1475f8a9f78ebb00948f956c914#p397285

      Take the Beaglebone black as another example the SOC says that it has 2 10/100/1000 ports, but in the fine print it is one 10/100/1000 port with a 2 port hub in front of it on chip. Throughput can't really be tested easily as the BBB ship with 10/100 Ethernet chipset support only. So a custom board with support chips for 10/100/1000 would need to me made. But my guess why this is not done is because a BBB can not saturate a gigabit link.

      Delete
    2. I did find some leaked documentation online for the CPU used in a Banana Pi "A20 User Manual 2013-03-22.pdf" And the only thing that suggests that it could possibly be able saturate gigabit Ethernet, without doing any tests (because I own no hardware with an A20 chip in it), is that it supports one USB 2.0 OTG and two USB 2.0 host ports. This is superior to the RPi, and it does suggest that there may no bottleneck to saturating the Gigabit Ethernet. If the maximum that you can get data into the CPU is 480 Mbps times three USB 2.0 ports, then you should in theory be able to saturate a 1000Mbps Ethernet link. I'm not saying that this is true, but it is a good sign.

      Delete
    3. http://gleenders.blogspot.ie/2014/07/beaglebone-black-rev-b-benchmarks.html is interesting, It shows some nice results. Good enough that I think that my next board will be a Banana Pi (or Banana Pro) and not a BeagleBone Black.

      Delete
    4. Got myself a Banana Pi, results are here:
      http://314256.blogspot.com/2014/11/banana-pi-gigabit-ethernet-throughput.html
      Summary to save you from clicking on the link "WOW, very very nice hardware".

      Delete
  2. The problem arises through the switch in use. Simply connect the two network adapters and retry...

    ReplyDelete
    Replies
    1. Thanks good idea. For jumbo packets it wound make sense that the problem was that the router did not support them (no accessible configuration option to enable them on the LAN side) and back to back NIC's with a crossover cable would remove the router from the equation. But even still jumbo packets come with their own problems, it is either on or off there is no support for both on the same link. But I might get around to testing it at some stage.Most of my testing is to show the maximum transfer possible in normalish configurations and jumbo packets are not really used much..

      Delete
  3. Hi, where is /etc/network/interfaces? I can't find it. My sistem is kodi. thanks

    ReplyDelete
    Replies
    1. Kodi, I never heard of that as an OS ? I've only heard of Kodi just the new name for the XBMC application.

      Maybe if you let me know what hardware it was installed on and the URL where you got Kodi from I may be able to help you, but I've not heard of it before as an OS. Kodi the application can run on lots of different operating systems, not just Linux. The /etc/network/interfaces file is on Debian based Linux distributions (Astra-Linux, Canaima, Collax, Cumulus Linux, Damn Small Linux, Debian JP, DoudouLinux, Embedded Debian, Euronode, Finnix, grml, Kanotix, KNOPPIX, Linex, Linspire, Linux Advanced, LMDE, MEPIS, M.N.I.S. OCERA, Ordissimo, Parsix, PureOS, RAYS LX, aptosid, Ubuntu, Univention Corporate Server, Xandros, Bananian, Raspian), it is a different file in a different location, sometimes with different options, in a different flavor of Linux.

      Delete