diff options
author | Joel Becker <joel.becker@oracle.com> | 2008-12-15 21:24:33 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-01-05 11:40:35 -0500 |
commit | 7bb458a58588f397068e4166c615e9fcc7480c16 (patch) | |
tree | a5d330c12f983837097f775e2d7c6c4d85fb9acd /fs | |
parent | e798b3f8a920c82a8e556dd54df97f0d3d0f9144 (diff) |
ocfs2: Another hamming code optimization.
In the calc_code_bit() function, we must find all powers of two beneath
the code bit number, *after* it's shifted by those powers of two. This
requires a loop to see where it ends up.
We can optimize it by starting at its most significant bit. This shaves
32% off the time, for a total of 67.6% shaved off of the original, naive
implementation.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ocfs2/blockcheck.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/fs/ocfs2/blockcheck.c b/fs/ocfs2/blockcheck.c index 1d5083cef3a2..f102ec939c90 100644 --- a/fs/ocfs2/blockcheck.c +++ b/fs/ocfs2/blockcheck.c | |||
@@ -39,6 +39,35 @@ | |||
39 | * c = # total code bits (d + p) | 39 | * c = # total code bits (d + p) |
40 | */ | 40 | */ |
41 | 41 | ||
42 | |||
43 | /* | ||
44 | * Find the log base 2 of 32-bit v. | ||
45 | * | ||
46 | * Algorithm found on http://graphics.stanford.edu/~seander/bithacks.html, | ||
47 | * by Sean Eron Anderson. Code on the page is in the public domain unless | ||
48 | * otherwise noted. | ||
49 | * | ||
50 | * This particular algorithm is credited to Eric Cole. | ||
51 | */ | ||
52 | static int find_highest_bit_set(unsigned int v) | ||
53 | { | ||
54 | |||
55 | static const int MultiplyDeBruijnBitPosition[32] = | ||
56 | { | ||
57 | 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, | ||
58 | 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 | ||
59 | }; | ||
60 | |||
61 | v |= v >> 1; /* first round down to power of 2 */ | ||
62 | v |= v >> 2; | ||
63 | v |= v >> 4; | ||
64 | v |= v >> 8; | ||
65 | v |= v >> 16; | ||
66 | v = (v >> 1) + 1; | ||
67 | |||
68 | return MultiplyDeBruijnBitPosition[(u32)(v * 0x077CB531UL) >> 27]; | ||
69 | } | ||
70 | |||
42 | /* | 71 | /* |
43 | * Calculate the bit offset in the hamming code buffer based on the bit's | 72 | * Calculate the bit offset in the hamming code buffer based on the bit's |
44 | * offset in the data buffer. Since the hamming code reserves all | 73 | * offset in the data buffer. Since the hamming code reserves all |
@@ -64,12 +93,21 @@ static unsigned int calc_code_bit(unsigned int i) | |||
64 | b = i + 1; | 93 | b = i + 1; |
65 | 94 | ||
66 | /* | 95 | /* |
96 | * As a cheat, we know that all bits below b's highest bit must be | ||
97 | * parity bits, so we can start there. | ||
98 | */ | ||
99 | p = find_highest_bit_set(b); | ||
100 | b += p; | ||
101 | |||
102 | /* | ||
67 | * For every power of two below our bit number, bump our bit. | 103 | * For every power of two below our bit number, bump our bit. |
68 | * | 104 | * |
69 | * We compare with (b + 1) becuase we have to compare with what b | 105 | * We compare with (b + 1) becuase we have to compare with what b |
70 | * would be _if_ it were bumped up by the parity bit. Capice? | 106 | * would be _if_ it were bumped up by the parity bit. Capice? |
107 | * | ||
108 | * We start p at 2^p because of the cheat above. | ||
71 | */ | 109 | */ |
72 | for (p = 0; (1 << p) < (b + 1); p++) | 110 | for (p = (1 << p); p < (b + 1); p <<= 1) |
73 | b++; | 111 | b++; |
74 | 112 | ||
75 | return b; | 113 | return b; |