mirror of
https://github.com/cuberite/libdeflate.git
synced 2025-09-14 23:06:17 -04:00
Speed up Adler-32 by unrolling loop
This commit is contained in:
parent
d46e893a0d
commit
fed4597943
@ -35,22 +35,62 @@
|
|||||||
*/
|
*/
|
||||||
#define MAX_BYTES_PER_CHUNK 5552
|
#define MAX_BYTES_PER_CHUNK 5552
|
||||||
|
|
||||||
|
/* Number of bytes to process per loop iteration */
|
||||||
|
#define UNROLL_FACTOR 4
|
||||||
|
|
||||||
u32
|
u32
|
||||||
adler32(const u8 *buffer, size_t size)
|
adler32(const u8 *buffer, size_t size)
|
||||||
{
|
{
|
||||||
u32 s1 = 1;
|
u32 s1 = 1;
|
||||||
u32 s2 = 0;
|
u32 s2 = 0;
|
||||||
const u8 *p = buffer;
|
const u8 *p = buffer;
|
||||||
const u8 * const end = p + size;
|
const u8 *end = p + size;
|
||||||
while (p != end) {
|
while (p != end) {
|
||||||
const u8 *chunk_end = p + min(end - p,
|
size_t chunk_size = min(end - p, MAX_BYTES_PER_CHUNK);
|
||||||
MAX_BYTES_PER_CHUNK);
|
const u8 *chunk_end = p + chunk_size;
|
||||||
do {
|
|
||||||
|
#if UNROLL_FACTOR > 1
|
||||||
|
size_t num_unrolled_iterations = chunk_size / UNROLL_FACTOR;
|
||||||
|
while (num_unrolled_iterations--) {
|
||||||
s1 += *p++;
|
s1 += *p++;
|
||||||
s2 += s1;
|
s2 += s1;
|
||||||
} while (p != chunk_end);
|
#if UNROLL_FACTOR >= 2
|
||||||
s1 %= 65521;
|
s1 += *p++;
|
||||||
s2 %= 65521;
|
s2 += s1;
|
||||||
|
#endif
|
||||||
|
#if UNROLL_FACTOR >= 3
|
||||||
|
s1 += *p++;
|
||||||
|
s2 += s1;
|
||||||
|
#endif
|
||||||
|
#if UNROLL_FACTOR >= 4
|
||||||
|
s1 += *p++;
|
||||||
|
s2 += s1;
|
||||||
|
#endif
|
||||||
|
#if UNROLL_FACTOR >= 5
|
||||||
|
s1 += *p++;
|
||||||
|
s2 += s1;
|
||||||
|
#endif
|
||||||
|
#if UNROLL_FACTOR >= 6
|
||||||
|
s1 += *p++;
|
||||||
|
s2 += s1;
|
||||||
|
#endif
|
||||||
|
#if UNROLL_FACTOR >= 7
|
||||||
|
s1 += *p++;
|
||||||
|
s2 += s1;
|
||||||
|
#endif
|
||||||
|
#if UNROLL_FACTOR >= 8
|
||||||
|
s1 += *p++;
|
||||||
|
s2 += s1;
|
||||||
|
#endif
|
||||||
|
BUILD_BUG_ON(UNROLL_FACTOR > 8);
|
||||||
|
}
|
||||||
|
#endif /* UNROLL_FACTOR > 1 */
|
||||||
|
while (p != chunk_end) {
|
||||||
|
s1 += *p++;
|
||||||
|
s2 += s1;
|
||||||
|
}
|
||||||
|
s1 %= DIVISOR;
|
||||||
|
s2 %= DIVISOR;
|
||||||
}
|
}
|
||||||
return (s2 << 16) | s1;
|
return (s2 << 16) | s1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user