aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crc32.c
diff options
context:
space:
mode:
authorJoakim Tjernlund <Joakim.Tjernlund@transmode.se>2010-05-24 17:33:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 11:07:06 -0400
commit836e2af92503f1642dbc3c3281ec68ec1dd39d2e (patch)
tree8b68f906e1ca6f39d159f306623da86f4e02f8cb /lib/crc32.c
parentd4977c78e9c7dd042f96f4a21d957bc25a561333 (diff)
crc32: major optimization
Precompute more crc32 values(0xcc00, 0xcc0000 and 0xcc000000) into tables. This increases the table size from 1KB to 4KB but the performance benfit makes it worth it: 28% faster on MPC8321, 266 MHz 2x faster on Core 2 Duo, 3.1GHz [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/crc32.c')
-rw-r--r--lib/crc32.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/lib/crc32.c b/lib/crc32.c
index bc5b936e9142..4855995fcde9 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -48,12 +48,20 @@ MODULE_LICENSE("GPL");
48#if CRC_LE_BITS == 8 || CRC_BE_BITS == 8 48#if CRC_LE_BITS == 8 || CRC_BE_BITS == 8
49 49
50static inline u32 50static inline u32
51crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab) 51crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
52{ 52{
53# ifdef __LITTLE_ENDIAN 53# ifdef __LITTLE_ENDIAN
54# define DO_CRC(x) crc = tab[(crc ^ (x)) & 255 ] ^ (crc >> 8) 54# define DO_CRC(x) crc = tab[0][(crc ^ (x)) & 255] ^ (crc >> 8)
55# define DO_CRC4 crc = tab[3][(crc) & 255] ^ \
56 tab[2][(crc >> 8) & 255] ^ \
57 tab[1][(crc >> 16) & 255] ^ \
58 tab[0][(crc >> 24) & 255]
55# else 59# else
56# define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) 60# define DO_CRC(x) crc = tab[0][((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
61# define DO_CRC4 crc = tab[0][(crc) & 255] ^ \
62 tab[1][(crc >> 8) & 255] ^ \
63 tab[2][(crc >> 16) & 255] ^ \
64 tab[3][(crc >> 24) & 255]
57# endif 65# endif
58 const u32 *b; 66 const u32 *b;
59 size_t rem_len; 67 size_t rem_len;
@@ -70,10 +78,7 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab)
70 b = (const u32 *)buf; 78 b = (const u32 *)buf;
71 for (--b; len; --len) { 79 for (--b; len; --len) {
72 crc ^= *++b; /* use pre increment for speed */ 80 crc ^= *++b; /* use pre increment for speed */
73 DO_CRC(0); 81 DO_CRC4;
74 DO_CRC(0);
75 DO_CRC(0);
76 DO_CRC(0);
77 } 82 }
78 len = rem_len; 83 len = rem_len;
79 /* And the last few bytes */ 84 /* And the last few bytes */
@@ -85,6 +90,7 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab)
85 } 90 }
86 return crc; 91 return crc;
87#undef DO_CRC 92#undef DO_CRC
93#undef DO_CRC4
88} 94}
89#endif 95#endif
90/** 96/**
@@ -117,7 +123,7 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
117u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) 123u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
118{ 124{
119# if CRC_LE_BITS == 8 125# if CRC_LE_BITS == 8
120 const u32 *tab = crc32table_le; 126 const u32 (*tab)[] = crc32table_le;
121 127
122 crc = __cpu_to_le32(crc); 128 crc = __cpu_to_le32(crc);
123 crc = crc32_body(crc, p, len, tab); 129 crc = crc32_body(crc, p, len, tab);
@@ -174,7 +180,7 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
174u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) 180u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
175{ 181{
176# if CRC_BE_BITS == 8 182# if CRC_BE_BITS == 8
177 const u32 *tab = crc32table_be; 183 const u32 (*tab)[] = crc32table_be;
178 184
179 crc = __cpu_to_be32(crc); 185 crc = __cpu_to_be32(crc);
180 crc = crc32_body(crc, p, len, tab); 186 crc = crc32_body(crc, p, len, tab);