tldr: Don't read more than ~1400 bytes of payload data at a time when using TCP.
I was wondering why my block read performance over TCP was so bad (~24 KB/s), but okay under UDP (~1,400 KB/s). (Using OptoMMP protocol from a .NET application)
Page 89 of 1465 OptoMMP Protocol Guide reads the following:
For these devices, you cannot read or write more than 2,034 bytes at a time via TCP.
2,034 bytes is larger than the ethernet frame size, so the ethernet frame is fragmented when requesting this much data and performance suffers ENORMOUSLY (at least on a PAC R1 that I tested on). I would think that network performance would be cut in half at most, but it is 50 times worse. I suspect the IO unit is really slow at fragmenting ethernet frames (or my computer is slow at reassembly??).
For block TCP reads, if the payload size is kept to 56 bytes below the ethernet MTU (around 1500), then the frame should not fragment and TCP performance is very close to UDP.
To find the MTU on a windows machine:
ping hostname -f -l sizeofdata
The hostname should be the IO unit, and the sizeofdata should start with 1472 and work your way down until the ping works. The MTU size will be the sizeofdata that works plus 28. At least, that is how it worked out on my system.
The MTU on my machine ended up being 1492. So the maximum OptoMMP payload for my machine is 1436 bytes to prevent frame fragmentation (there is also another 16 bytes of OptoMMP header data). My TCP performance went up to ~1,300 KB/s with this change - almost as fast as UDP!
Would it be possible to get the OptoMMP protocol guide updated to show that 2,034 will not be the optimal setting for payload size?
Also, the next paragraph in the guide states:
Within these limits, you can read or write to large areas within the memory map using a block read or write. (Each area of the map is shown under a separate heading in the following pages.) For example, using TCP, you could read or write up to 2034 bytes of data—about a third of the entire area—in the “(Expanded) Analog & Digital Point Configuration—Read/Write” area shown on page 90.
The third of the entire area comment is wrong. The configuration area is 64 modules * 64 points * 192 bytes = 786,432 bytes. 2034/786,432 = 0.26%