diff options
author | Alexander van Heukelum <heukelum@mailshack.com> | 2008-03-09 16:01:04 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-26 13:21:16 -0400 |
commit | 6fd92b63d0626a8fe7eb8e2e50d19ecaa18cb412 (patch) | |
tree | 840f6cf998c251cdfcae37a03f34b34ac5bea3a5 /include | |
parent | 18e413f7193ed2f6991d959863f46330813aa242 (diff) |
x86: change x86 to use generic find_next_bit
The versions with inline assembly are in fact slower on the machines I
tested them on (in userspace) (Athlon XP 2800+, p4-like Xeon 2.8GHz, AMD
Opteron 270). The i386-version needed a fix similar to 06024f21 to avoid
crashing the benchmark.
Benchmark using: gcc -fomit-frame-pointer -Os. For each bitmap size
1...512, for each possible bitmap with one bit set, for each possible
offset: find the position of the first bit starting at offset. If you
follow ;). Times include setup of the bitmap and checking of the
results.
Athlon Xeon Opteron 32/64bit
x86-specific: 0m3.692s 0m2.820s 0m3.196s / 0m2.480s
generic: 0m2.622s 0m1.662s 0m2.100s / 0m1.572s
If the bitmap size is not a multiple of BITS_PER_LONG, and no set
(cleared) bit is found, find_next_bit (find_next_zero_bit) returns a
value outside of the range [0, size]. The generic version always returns
exactly size. The generic version also uses unsigned long everywhere,
while the x86 versions use a mishmash of int, unsigned (int), long and
unsigned long.
Using the generic version does give a slightly bigger kernel, though.
defconfig: text data bss dec hex filename
x86-specific: 4738555 481232 626688 5846475 5935cb vmlinux (32 bit)
generic: 4738621 481232 626688 5846541 59360d vmlinux (32 bit)
x86-specific: 5392395 846568 724424 6963387 6a40bb vmlinux (64 bit)
generic: 5392458 846568 724424 6963450 6a40fa vmlinux (64 bit)
Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-x86/bitops.h | 6 | ||||
-rw-r--r-- | include/asm-x86/bitops_32.h | 16 | ||||
-rw-r--r-- | include/asm-x86/bitops_64.h | 2 |
3 files changed, 6 insertions, 18 deletions
diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h index 1ae7b270a1ef..31e408de90c6 100644 --- a/include/asm-x86/bitops.h +++ b/include/asm-x86/bitops.h | |||
@@ -306,6 +306,12 @@ static int test_bit(int nr, const volatile unsigned long *addr); | |||
306 | #undef BIT_ADDR | 306 | #undef BIT_ADDR |
307 | #undef ADDR | 307 | #undef ADDR |
308 | 308 | ||
309 | unsigned long find_next_bit(const unsigned long *addr, | ||
310 | unsigned long size, unsigned long offset); | ||
311 | unsigned long find_next_zero_bit(const unsigned long *addr, | ||
312 | unsigned long size, unsigned long offset); | ||
313 | |||
314 | |||
309 | #ifdef CONFIG_X86_32 | 315 | #ifdef CONFIG_X86_32 |
310 | # include "bitops_32.h" | 316 | # include "bitops_32.h" |
311 | #else | 317 | #else |
diff --git a/include/asm-x86/bitops_32.h b/include/asm-x86/bitops_32.h index 2513a81f82aa..7c9ed759afb2 100644 --- a/include/asm-x86/bitops_32.h +++ b/include/asm-x86/bitops_32.h | |||
@@ -40,14 +40,6 @@ static inline int find_first_zero_bit(const unsigned long *addr, unsigned size) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * find_next_zero_bit - find the first zero bit in a memory region | ||
44 | * @addr: The address to base the search on | ||
45 | * @offset: The bit number to start searching at | ||
46 | * @size: The maximum size to search | ||
47 | */ | ||
48 | int find_next_zero_bit(const unsigned long *addr, int size, int offset); | ||
49 | |||
50 | /** | ||
51 | * __ffs - find first bit in word. | 43 | * __ffs - find first bit in word. |
52 | * @word: The word to search | 44 | * @word: The word to search |
53 | * | 45 | * |
@@ -83,14 +75,6 @@ static inline unsigned find_first_bit(const unsigned long *addr, unsigned size) | |||
83 | } | 75 | } |
84 | 76 | ||
85 | /** | 77 | /** |
86 | * find_next_bit - find the first set bit in a memory region | ||
87 | * @addr: The address to base the search on | ||
88 | * @offset: The bit number to start searching at | ||
89 | * @size: The maximum size to search | ||
90 | */ | ||
91 | int find_next_bit(const unsigned long *addr, int size, int offset); | ||
92 | |||
93 | /** | ||
94 | * ffz - find first zero in word. | 78 | * ffz - find first zero in word. |
95 | * @word: The word to search | 79 | * @word: The word to search |
96 | * | 80 | * |
diff --git a/include/asm-x86/bitops_64.h b/include/asm-x86/bitops_64.h index 365f8207ea59..65b20fb2ae78 100644 --- a/include/asm-x86/bitops_64.h +++ b/include/asm-x86/bitops_64.h | |||
@@ -6,9 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | extern long find_first_zero_bit(const unsigned long *addr, unsigned long size); | 8 | extern long find_first_zero_bit(const unsigned long *addr, unsigned long size); |
9 | extern long find_next_zero_bit(const unsigned long *addr, long size, long offset); | ||
10 | extern long find_first_bit(const unsigned long *addr, unsigned long size); | 9 | extern long find_first_bit(const unsigned long *addr, unsigned long size); |
11 | extern long find_next_bit(const unsigned long *addr, long size, long offset); | ||
12 | 10 | ||
13 | /* return index of first bet set in val or max when no bit is set */ | 11 | /* return index of first bet set in val or max when no bit is set */ |
14 | static inline long __scanbit(unsigned long val, unsigned long max) | 12 | static inline long __scanbit(unsigned long val, unsigned long max) |