Our experience has been that low-end print servers have atrocious performance, and after simply measuring the horrid transfer time, we decided to find out why. This is the result of our research: we hope it's helpful to others needing this information.
Note, however, that the internal HP JetDirect 610N EIO card probably doesn't have an extra layer of interfacing (parallel or USB) between them and the printer controller, so it may not be fair to compare the $260 JetDirect card with the other units that do have the extra layer. The better test of HP would be to use an external box - we just didn't have one at hand to try.
|
We used two methods of sending data to the printers, depending on what was supported by the print server.
The largest TCP payload in a single Ethernet frame is 1460 bytes, and many advertised RWINs are multiples of this value. This means that the sender can have that many outstanding frames. As long as the receiver can keep up by always acknowledging frames within the RWIN window, then the sender can transmit at full speed.
But if the print server is either underpowered, or has very limited RAM for network buffers (or both), it will advertise a small window so that it never has to keep that much data around at one time. This does allow low-powered hardware to talk on the Ethernet, but it totally destroys network performance.
Some devices had as small as a 1024-byte window, which is not even a full Ethernet frame, so the sender would transmit a partial frame, wait for an ACK, send the next one, wait for an ACK, and so on. The Ethernet was mostly unused in this case.
The first device we looked at - the Hawking H-PS1U - had a small RWIN and a very long delay in sending acknowedgements. A snippet taken from our tcpdump network sniffer output shows the nature of the conversation:
The timestamps show that our LINUX system was able to send data quite timely, but it was only able to send two frames before the window of 2920 filled up. In addition, the print server took more than 100 milliseconds -- more than a tenth of a second -- to acknowledge this small window. This simply destroys network throughput, and it points to "ACK latency" as another parameter that must be considered when measuring network throughput. This device gets about 24kbyte/sec throughput.Timestamp LINUX PRTSERVER delta µsec 2.029849 1460 bytes ----------> + 18 µsec start to fill window 2.029856 1460 bytes ----------> + 7 µsec oops - filled (gotta wait) 2.146525 <----------------- ACK +116669 µsec finally got an ACK 2.146542 1460 bytes ----------> + 17 µsec start with empty window 2.146549 1460 bytes ----------> + 7 µsec oops - filled again. Wait. 2.263159 <----------------- ACK +116610 µsec finally got an ACK 2.263172 1460 bytes ----------> + 13 µsec 2.263179 1460 bytes ----------> + 7 µsec 2.379830 <----------------- ACK +116651 µsec
We'll now talk about each device in turn.
Running tcpdump shows that the unit has not only a small
(2920 bytes, or two frames) RWIN, but hideous ACK latency:
it's not clear why this is the case, but 24kbytes/second is
nearly two orders of magnitude slower than a real HP JetDirect
card.
# tcpdump -ttt -p -i eth0 tcp port printer tcpdump: listening on eth0 000000 LINUX.3692 > HPS1U.printer: S 378464836:378464836(0) win 32120 \ <mss 1460,sackOK,timestamp 889822604[|tcp]> (DF) This is the initial connection from LINUX to the print server, and we're requesting a 32120 byte TCP window. If granted, it means that LINUX would be able to send 22 full-sized Ethernet frames before getting an acknowledgement from HPS1U. 006540 HPS1U.printer > LINUX.3692: S 81752064:81752064(0) ack 378464837 win 2920 \ <mss 1460> This is the response from the print server, and it is offering only a 2920 byte TCP window, which is just two full-sized Ethernet frames before an ACK is required. Note also that the response arrives 6.5 milliseconds later. 000076 LINUX.3692 > HPS1U.printer: . ack 1 win 32120 (DF) 000321 LINUX.3692 > HPS1U.printer: P 1:6(5) ack 1 win 32120 (DF) 006688 HPS1U.printer > LINUX.3692: . ack 6 win 2920 002097 HPS1U.printer > LINUX.3692: P 1:2(1) ack 6 win 2920 000016 LINUX.3692 > HPS1U.printer: . ack 2 win 32120 (DF) 000197 LINUX.3692 > HPS1U.printer: P 6:40(34) ack 2 win 32120 (DF) 010422 HPS1U.printer > LINUX.3692: P 2:3(1) ack 40 win 2920 000173 LINUX.3692 > HPS1U.printer: P 40:296(256) ack 3 win 32120 (DF) 000113 LINUX.3692 > HPS1U.printer: P 296:1064(768) ack 3 win 32120 (DF) 000106 LINUX.3692 > HPS1U.printer: P 1064:1832(768) ack 3 win 32120 (DF) 000110 LINUX.3692 > HPS1U.printer: P 1832:2600(768) ack 3 win 32120 (DF) 004788 HPS1U.printer > LINUX.3692: . ack 296 win 2920 002596 HPS1U.printer > LINUX.3692: . ack 1064 win 2920 013181 HPS1U.printer > LINUX.3692: . ack 1832 win 2920 The previous is in the early part of the conversation, and there are small bits of data exchanged before the big image data gets sent. We see the effect of TCP slow-start that ramps up the size of the data being sent. ... (some data deleted) Now we skip ahead to where the "real" image data is well underway, and the pattern is clear: (microseconds) 000021 LINUX.3692 > HPS1U.printer: P 20120:21580(1460) ack 3 win 32120 (DF) 000007 LINUX.3692 > HPS1U.printer: P 21580:23040(1460) ack 3 win 32120 (DF) 117667 HPS1U.printer > LINUX.3692: . ack 23040 win 2920 This previous triplet, typical of about 7,000 seen in the conversation, shows that LINUX sends two full Ethernet frames - 2920 bytes - but it necessarily must pause until it gets an acknowledgement for at least part the outstanding data. These two frames are transmitted in roughly 30 microseconds. But the ACK response from the print server comes 117 milliseconds later -- more than at tenth of a second -- which is an eternity in IP time. When we consider the total time it takes for this triplet - 117695 µsec to send 2920 bytes -- this yields: 1000000 / 117695 = 8.4965 triplets per seconds 8.4965 trip/sec * 2920 = 24801 bytes/second 000018 LINUX.3692 > HPS1U.printer: P 23040:24500(1460) ack 3 win 32120 (DF) 000007 LINUX.3692 > HPS1U.printer: P 24500:25960(1460) ack 3 win 32120 (DF) 117969 HPS1U.printer > LINUX.3692: . ack 25960 win 2920 ... same thing... 000013 LINUX.3692 > HPS1U.printer: P 25960:27420(1460) ack 3 win 32120 (DF) 000005 LINUX.3692 > HPS1U.printer: P 27420:28880(1460) ack 3 win 32120 (DF) 118146 HPS1U.printer > LINUX.3692: . ack 28880 win 2920 ... same thing 000019 LINUX.3692 > HPS1U.printer: P 28880:30340(1460) ack 3 win 32120 (DF) 000006 LINUX.3692 > HPS1U.printer: P 30340:31800(1460) ack 3 win 32120 (DF) 117999 HPS1U.printer > LINUX.3692: . ack 31800 win 2920 ... many more deleted (skipping to the end) 000013 LINUX.3692 > HPS1U.printer: P 22222340:22223800(1460) ack 3 win 32120 (DF) 000008 LINUX.3692 > HPS1U.printer: P 22223800:22225260(1460) ack 3 win 32120 (DF) 118102 HPS1U.printer > LINUX.3692: . ack 22225260 win 2920 ... final "slow triplet" 000013 LINUX.3692 > HPS1U.printer: P 22225260:22226473(1213) ack 3 win 32120 (DF) 117267 HPS1U.printer > LINUX.3692: P 3:4(1) ack 22226473 win 2920 000107 LINUX.3692 > HPS1U.printer: P 22226473:22226501(28) ack 4 win 32120 (DF) 011000 HPS1U.printer > LINUX.3692: P 4:5(1) ack 22226501 win 2920 000041 LINUX.3692 > HPS1U.printer: P 22226501:22226562(61) ack 5 win 32120 (DF) 007429 HPS1U.printer > LINUX.3692: P 5:6(1) ack 22226562 win 2920 000053 LINUX.3692 > HPS1U.printer: F 22226562:22226562(0) ack 6 win 32120 (DF) 007759 HPS1U.printer > LINUX.3692: . ack 22226563 win 2920 000082 LINUX.3692 > HPS1U.printer: R 400691399:400691399(0) win 0 000609 HPS1U.printer > LINUX.3692: F 6:6(0) ack 22226563 win 2920 000018 LINUX.3692 > HPS1U.printer: R 400691399:400691399(0) win 0 ... closing down the conversation normally
It advertises a 1024-byte receive window, and oddly generates two ACKs for each packet sent: the first one serves as an ack for the previous data, but provides a new RWIN of 0 - this tells the sender that it got the data, but no more should be sent. Presumably the device is processing the data just acknowledge, and this "ACK-but-don't-send-more-data" does allow the sender to prepare to start refilling the window.
A moment later a similar ACK opens up the window to the "full" 1024 bytes,
restarting the data stream to the device. Once again we see that the
Linux system has very rapid response to the ACK - ~13 µsec -
but the print server takes much longer to process.
delta µsec 000013 LINUX.3711 > NETGEAR.9100: P 10152:11176(1024) ack 1 win 32120 (DF) 010399 NETGEAR.9100 > LINUX.3711: P ack 11176 win 0 001742 NETGEAR.9100 > LINUX.3711: P ack 11176 win 1024 000012 LINUX.3711 > NETGEAR.9100: P 11176:12184(1008) ack 1 win 32120 (DF) 010371 NETGEAR.9100 > LINUX.3711: P ack 12184 win 16 001764 NETGEAR.9100 > LINUX.3711: P ack 12184 win 1024 000014 LINUX.3711 > NETGEAR.9100: P 12184:13208(1024) ack 1 win 32120 (DF) 010391 NETGEAR.9100 > LINUX.3711: P ack 13208 win 0 001742 NETGEAR.9100 > LINUX.3711: P ack 13208 win 1024
This is a parallel-printer model, and it supports most of the common protocols. Netware, Appletalk, NETBEUI, and TCP/IP via the lpr daemon and IPP. It doesn't support JetDirect 9100/tcp printing.
The unit acquired an address from DHCP immediately, and it was printing in less than a minute after hookup. We never installed any of the supplied software. It had the best performance from any standalone box, and was also the most expensive.
This unit had similar TCP/IP behavior (1024-byte RWIN), though it had
some odd behavior now and then during the transfer:
000017 LINUX.3719 > LINKSYS.printer: P 14120:15144(1024) ack 3 win 32120 (DF) 005193 LINKSYS.printer > LINUX.3719: P ack 15144 win 0 000978 LINKSYS.printer > LINUX.3719: P ack 15144 win 1024 Mostly normal behavior for a 1024-byte window, though the win 0 is still puzzling. 000014 LINUX.3719 > LINKSYS.printer: P 15144:16168(1024) ack 3 win 32120 (DF) 005496 LINKSYS.printer > LINUX.3719: P ack 16168 win 0 000984 LINKSYS.printer > LINUX.3719: P ack 16168 win 1024 .. ditto ... 000012 LINUX.3719 > LINKSYS.printer: P 16168:17192(1024) ack 3 win 32120 (DF) 005686 LINKSYS.printer > LINUX.3719: P ack 17192 win 0 195709 LINUX.3719 > LINKSYS.printer: . ack 3 win 32120 (DF) 002777 LINKSYS.printer > LINUX.3719: . ack 17192 win 0 397220 LINUX.3719 > LINKSYS.printer: . ack 3 win 32120 (DF) 002697 LINKSYS.printer > LINUX.3719: . ack 17192 win 0 797315 LINUX.3719 > LINKSYS.printer: . ack 3 win 32120 (DF) 002799 LINKSYS.printer > LINUX.3719: . ack 17192 win 0 625099 LINKSYS.printer > LINUX.3719: P ack 17192 win 1024 open up window again This is a very odd exchange: the device seems to be "marking time" while it's busy, and the Linux system is sending no-data ACKs to ACKS simply to be responsive. This stall is more than two seconds, and they happen periodically throughout the transfer.
For routine office work (say, printing text reports out of an accounting system), all of these are more than suitable and seem to be reliable and easy to set up. But for high-performance printing, we believe that none of them is even close to suitable.
We received above-and-beyond tech support from Troy (other vendors didn't respond to email), and there was nothing not to like about this unit. We chose the PocketPro 100S and have been very happy with it.
---
A special thanks to SYNACK, a moderator at Broadband Reports for his helpful input on this analysis.
Navigate: More Tech Tips