Path: utzoo!mnetor!uunet!lll-winken!lll-tis!ames!ll-xn!adelie!infinet!rhorn From: rhorn@infinet.UUCP (Rob Horn) Newsgroups: comp.protocols.tcp-ip Subject: Checksums, CRC's, and NFS Message-ID: <1108@infinet.UUCP> Date: 2 Apr 88 02:57:21 GMT Reply-To: rhorn@infinet.UUCP (Rob Horn) Organization: Infinet, Inc. North Andover, MA Lines: 61 There are sometimes good reasons to use CRC rather than just checksums, especially when in the asynch world. We send a lot of data over hostile links using asynch and we have found that one of the more anti-social failure modes of port sharing devices and muxes is byte or buffer swapping. Checksums don't catch these. CRC's do, and they cost relatively little. Our CRC code compiles into only nine (9) instructions per byte, and could be cut to seven (7) if we went to assembler. This is not as good as checksums, but it is nothing when compared to the CPU cost of servicing the interrupts for the comm device. I think that CRC's have gotten too much bad press because people think they are expensive. So our CRC code (sans 512 byte table) is attached at the end. On the other hand, for reliable high speed links (like LANs) I think Sun made the right decision to drop even checksums. With a typical 8 KB block, even if the checksum cost is down to 1 microsecond per byte you have added 8 milliseconds to the response. This is a big portion of the total response time for a disk on the same LAN, especially for a cache hit. But Sun should have made checksumming a per mount option, to accomodate those cases where the connection is slower or less reliable than a LAN. Rob Horn ...harvard!adelie!infinet!rhorn, ..!ulowell!infinet!rhorn /* * A simple table driven CRC calculator. */ extern BYTE CRC_TABLE [256] [2]; rx_crc(crc, buffer, len) char crc[2]; char *buffer; short len; { #define high 1 #define low 0 register BYTE *crcptr; register char crclow; register char crchigh; register char *workptr; register char *limit; /* This should only be a register on 68K or VAXen */ /* Not on Intel processors */ crclow = 0xff; crchigh = 0xff; limit = buffer + len; workptr = buffer; while( workptr < limit) { crcptr = CRC_TABLE [(unsigned char) ( *workptr++ ^ crclow)]; crclow = crcptr[high] ^ crchigh; crchigh = crcptr[low]; } crc[low] = crclow; crc[high] = crchigh; } -- Rob Horn UUCP: ...harvard!adelie!infinet!rhorn Snail: Infinet, 40 High St., North Andover, MA (Note: harvard!infinet path is in maps but not working yet)