summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSun He <sunheehnus@gmail.com>2014-12-02 14:46:15 +0800
committerantirez <antirez@gmail.com>2014-12-09 12:46:43 +0100
commit5fc55a1afa1ac9f1789589253076690e13ae41a6 (patch)
treec76777b08e8feac0fd7edbad1a2cc6f2f0a05ce0
parent5ab2c31189bc534c53418fd74afdbf0e70088fd6 (diff)
downloadredis-5fc55a1afa1ac9f1789589253076690e13ae41a6.tar.gz
bitops.c/redisPopcount: little optimization in loop
-rw-r--r--src/bitops.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/bitops.c b/src/bitops.c
index 94c7f3537..15ce787cf 100644
--- a/src/bitops.c
+++ b/src/bitops.c
@@ -70,16 +70,19 @@ size_t redisPopcount(void *s, long count) {
count--;
}
- /* Count bits 16 bytes at a time */
+ /* Count bits 28 bytes at a time */
p4 = (uint32_t*)p;
- while(count>=16) {
- uint32_t aux1, aux2, aux3, aux4;
+ while(count>=28) {
+ uint32_t aux1, aux2, aux3, aux4, aux5, aux6, aux7;
aux1 = *p4++;
aux2 = *p4++;
aux3 = *p4++;
aux4 = *p4++;
- count -= 16;
+ aux5 = *p4++;
+ aux6 = *p4++;
+ aux7 = *p4++;
+ count -= 28;
aux1 = aux1 - ((aux1 >> 1) & 0x55555555);
aux1 = (aux1 & 0x33333333) + ((aux1 >> 2) & 0x33333333);
@@ -89,10 +92,19 @@ size_t redisPopcount(void *s, long count) {
aux3 = (aux3 & 0x33333333) + ((aux3 >> 2) & 0x33333333);
aux4 = aux4 - ((aux4 >> 1) & 0x55555555);
aux4 = (aux4 & 0x33333333) + ((aux4 >> 2) & 0x33333333);
- bits += ((((aux1 + (aux1 >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24) +
- ((((aux2 + (aux2 >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24) +
- ((((aux3 + (aux3 >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24) +
- ((((aux4 + (aux4 >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24);
+ aux5 = aux5 - ((aux5 >> 1) & 0x55555555);
+ aux5 = (aux5 & 0x33333333) + ((aux5 >> 2) & 0x33333333);
+ aux6 = aux6 - ((aux6 >> 1) & 0x55555555);
+ aux6 = (aux6 & 0x33333333) + ((aux6 >> 2) & 0x33333333);
+ aux7 = aux7 - ((aux7 >> 1) & 0x55555555);
+ aux7 = (aux7 & 0x33333333) + ((aux7 >> 2) & 0x33333333);
+ bits += ((((aux1 + (aux1 >> 4)) & 0x0F0F0F0F) +
+ ((aux2 + (aux2 >> 4)) & 0x0F0F0F0F) +
+ ((aux3 + (aux3 >> 4)) & 0x0F0F0F0F) +
+ ((aux4 + (aux4 >> 4)) & 0x0F0F0F0F) +
+ ((aux5 + (aux5 >> 4)) & 0x0F0F0F0F) +
+ ((aux6 + (aux6 >> 4)) & 0x0F0F0F0F) +
+ ((aux7 + (aux7 >> 4)) & 0x0F0F0F0F))* 0x01010101) >> 24;
}
/* Count the remaining bytes. */
p = (unsigned char*)p4;