[parisc-linux-cvs] linux-2.6 tausq

Randolph Chung randolph at tausq.org
Fri Oct 8 18:38:22 MDT 2004


> Modified files:
> 	.              : Makefile 
> 	arch/parisc/lib: checksum.c 
> 
> Log message:
> 2.6.9-rc3-pa4: small tweaks to the checksumming routine

This small change improves the checksum perf by ~30-40%. netperf results
for the tcp streaming test are about 15% better vs what we had before.

checksums still need lots of work though.....

Index: arch/parisc/lib/checksum.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/lib/checksum.c,v
retrieving revision 1.4
diff -u -p -r1.4 checksum.c
--- arch/parisc/lib/checksum.c	4 Oct 2004 19:12:50 -0000	1.4
+++ arch/parisc/lib/checksum.c	9 Oct 2004 00:02:26 -0000
@@ -24,6 +24,13 @@
 #include <asm/string.h>
 #include <asm/uaccess.h>
 
+#define addc(_t,_r)                     \
+	__asm__ __volatile__ (          \
+"       add             %0, %1, %0\n"   \
+"       addc            %0, %%r0, %0\n" \
+	: "=r"(_t)                      \
+	: "r"(_r), "0"(_t));
+
 static inline unsigned short from32to16(unsigned int x)
 {
 	/* 32 bits --> 16 bits + carry */
@@ -56,16 +63,25 @@ static inline unsigned int do_csum(const
 		}
 		count >>= 1;		/* nr of 32-bit words.. */
 		if (count) {
-			unsigned int carry = 0;
-			do {
+			while (count >= 4) {
+				unsigned int r1, r2, r3, r4;
+				r1 = *(unsigned int *)(buff + 0);
+				r2 = *(unsigned int *)(buff + 4);
+				r3 = *(unsigned int *)(buff + 8);
+				r4 = *(unsigned int *)(buff + 12);
+				addc(result, r1);
+				addc(result, r2);
+				addc(result, r3);
+				addc(result, r4);
+				count -= 4;
+				buff += 16;
+			}
+			while (count) {
 				unsigned int w = *(unsigned int *) buff;
 				count--;
 				buff += 4;
-				result += carry;
-				result += w;
-				carry = (w > result);
-			} while (count);
-			result += carry;
+				addc(result, w);
+			}
 			result = (result & 0xffff) + (result >> 16);
 		}
 		if (len & 2) {
@@ -88,11 +104,7 @@ out:
 unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
 {
 	unsigned int result = do_csum(buff, len);
-
-	/* add in old sum, and carry.. */
-	result += sum;
-	if(sum > result)
-		result += 1;
+	addc(result, sum);
 	return result;
 }
 


More information about the parisc-linux-cvs mailing list