Page 1 of 1

USB_VCP performance

Posted: Wed May 20, 2015 6:48 pm
by manitou
I have measured USB performance (latency, read rate) on various MCU's (teensy, DUE, maple, UNO) using the framework described at
http://www.pjrc.com/teensy/benchmark_us ... ceive.html

Using the same host harness (on Ubuntu laptop), I used the following pyboard program to measure latency

Code: Select all

#  from teensy latency_test /dev/ttyACM0
import pyb
usb_vcp = pyb.USB_VCP()
pyb.LED(1).on()
pyb.delay(5000)
# wait for host to connect to ACM0
while not usb_vcp.isconnected():
	pass
pyb.LED(1).off()

while True:
	if usb_vcp.any() :
		x = usb_vcp.read(1)
		if x == b'x' :
			usb_vcp.write('0')
			usb_vcp.write('1')
			usb_vcp.write('2')
			usb_vcp.write('x')

The results for the pyboard were a bit slow compared to teensy 3.1 and even UNO, and the test failed if the host tried sending more than 500 bytes. The 10ms delay is probably dictated by timer3 USBD_CDC_POLLING_INTERVAL

Code: Select all

	                 teensy 3.1             UNO             pyboard
       latency @ 1 bytes: 0.10 ms 	     4.09 ms 	     10.00 ms 
       latency @ 2 bytes: 0.10 ms 	     4.09 ms 	     10.00 ms 
       latency @ 12 bytes: 0.10 ms	     4.09 ms 	     10.00 ms 
       latency @ 30 bytes: 0.14 ms 	     4.09 ms 	     10.00 ms 
       latency @ 62 bytes: 0.19 ms	     8.19 ms 	     10.00 ms 
       latency @ 71 bytes: 0.21 ms	     8.19 ms 	     10.00 ms 
       latency @ 128 bytes: 0.26 ms	     12.28 ms 	     10.00 ms 
       latency @ 500 bytes: 0.64 ms	     45.05 ms 	     20.00 ms 
       latency @ 1000 bytes: 1.07 ms	     86.01 ms 		?
       latency @ 2000 bytes: 2.03 ms	     172.04 ms 		?
       latency @ 4000 bytes: 3.88 ms	     344.07 ms 		?
       latency @ 8000 bytes: 7.45 ms	     684.04 ms 		?

The readbytes test did NOT really work on the pyboard. the host sends 30000 bytes for a total of 1 million bytes. In fact, the host seems to send at its maximum rate as there appears to be no feedback (flow control) from the pyboard USB. With no "recv" in the pyboard program, the host side is happy to send away! Here is the little pyboard receiver

Code: Select all

#  from teensy latency_test /dev/ttyACM0    TODO ??
# recv is blocking, read is not
import pyb
usb_vcp = pyb.USB_VCP()
pyb.LED(1).on()
pyb.delay(5000)
# wait for host to connect to ACM0
while not usb_vcp.isconnected():
	pass
pyb.LED(1).off()

while True:
		x = usb_vcp.recv(500)

As usual, I could have messed up the Python (not my "native" language), but if not, I'm surprised that the pyboard USB_VCP is not doing some sort of USB flow control??

readbytes on teensy 3.1 averages 1,150,244 bytes/second, on UNO average is 11,761 bytes/sec.

EDIT: if I change the host send size from 30000 to 512, then the pyboard does do some recv's -- though not 1 million bytes worth.

Re: USB_VCP performance

Posted: Wed May 20, 2015 11:28 pm
by dhylands
Interesting. I'll have to dig into the USB stuff.

I've just been writing some code to do file transfers from the host to the pyboard and I wound up using 512 byte transfers with an explicit ack having to be sent back to the host to send the next 512 bytes.

Re: USB_VCP performance

Posted: Thu May 21, 2015 12:54 am
by manitou
well, i've made some progress sending in 512 byte chunks from the host and using the following program to recv, I am receiving 1 million bytes +

Code: Select all

#  from teensy receive_test /dev/ttyACM0   
# recv is blocking (timeout 5000ms), read is not
import pyb

msg = 'nothing'
sw = pyb.Switch()
sw.callback(lambda:uart.write(msg))
uart = pyb.UART(1, 9600)
uart.write('starting  ')
buff = bytearray(500)
bytes =0

usb_vcp = pyb.USB_VCP()
pyb.LED(1).on()
pyb.delay(5000)
# wait for host to connect to ACM0
while not usb_vcp.isconnected():
	pass
pyb.LED(1).off()


while True:
#		uart.write('recv {} \r\n'.format(bytes))
		n = usb_vcp.recv(buff)
		if n != 0 :
			bytes += n
			msg = 'bytes {} \r\n'.format(bytes)

the host send rate using 512-byte chunks is 512,043 bytes/second.

I still think the USB_VCP should be doing some sort of USB flow control ...