Staging: batman-adv: Calculate hamming weight using optimized kernel functions
authorSven Eckelmann <sven.eckelmann@gmx.de>
Sat, 4 Sep 2010 23:58:22 +0000 (01:58 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sun, 5 Sep 2010 07:29:43 +0000 (00:29 -0700)
The Kernighan algorithm is not able to calculate the number of set bits
in parallel and the compiler cannot replace it with optimized
instructions.

The kernel provides specialised functions for each cpu which can either
use a software implementation or hardware instruction depending on the
target cpu.

Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/batman-adv/TODO
drivers/staging/batman-adv/bitarray.c
drivers/staging/batman-adv/bitarray.h

index 9c5aea20be153d24de2e25ac5dac81a64ed4645b..d8bf845b9bba5baa4e00d3f6bb32489e70a6a3fc 100644 (file)
@@ -1,4 +1,3 @@
- * Use hweight* for hamming weight calculation
  * Save/cache packets direktly as skb instead of using a normal memory region
    and copying it in a skb using send_raw_packet and similar functions
  * Request a new review
index dd4193c99d4ec3fc81a1e9ea7cffda247dd11a6c..9dbaf1e8e6a5152b8f73fe258b86f13901945caa 100644 (file)
@@ -22,6 +22,8 @@
 #include "main.h"
 #include "bitarray.h"
 
+#include <linux/bitops.h>
+
 /* returns true if the corresponding bit in the given seq_bits indicates true
  * and curr_seqno is within range of last_seqno */
 uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
@@ -187,21 +189,14 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
 }
 
 /* count the hamming weight, how many good packets did we receive? just count
- * the 1's. The inner loop uses the Kernighan algorithm, see
- * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
+ * the 1's.
  */
 int bit_packet_count(TYPE_OF_WORD *seq_bits)
 {
        int i, hamming = 0;
-       TYPE_OF_WORD word;
 
-       for (i = 0; i < NUM_WORDS; i++) {
-               word = seq_bits[i];
+       for (i = 0; i < NUM_WORDS; i++)
+               hamming += hweight_long(seq_bits[i]);
 
-               while (word) {
-                       word &= word-1;
-                       hamming++;
-               }
-       }
        return hamming;
 }
index 01897d6962d03655813e978f32ee5764e9b873f9..28479ea7f7f7d45f531683c9b34a5e7e00973a88 100644 (file)
@@ -22,7 +22,8 @@
 #ifndef _NET_BATMAN_ADV_BITARRAY_H_
 #define _NET_BATMAN_ADV_BITARRAY_H_
 
-/* you should choose something big, if you don't want to waste cpu */
+/* you should choose something big, if you don't want to waste cpu
+ * and keep the type in sync with bit_packet_count */
 #define TYPE_OF_WORD unsigned long
 #define WORD_BIT_SIZE (sizeof(TYPE_OF_WORD) * 8)