diff options
author | Joakim Tjernlund <Joakim.Tjernlund@transmode.se> | 2010-05-24 17:33:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-25 11:07:06 -0400 |
commit | 836e2af92503f1642dbc3c3281ec68ec1dd39d2e (patch) | |
tree | 8b68f906e1ca6f39d159f306623da86f4e02f8cb /lib/crc32.c | |
parent | d4977c78e9c7dd042f96f4a21d957bc25a561333 (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.c | 24 |
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 | ||
50 | static inline u32 | 50 | static inline u32 |
51 | crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab) | 51 | crc32_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) | |||
117 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) | 123 | u32 __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) | |||
174 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | 180 | u32 __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); |