🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.c.moderated
Article #2538

Re: Efficiency Question : bits vs. bytes (or anything else, for that matter)

#2538
From: telnet user
Date: Sat, 06 Apr 1996 14:51
107 lines
3757 bytes
Richard A. O'Keefe (ok@cs.rmit.edu.au) wrote:
: [ bitset operations ]

: Note the following trick for walking through an array of unsigned longs,
: processing each bit.  It assumes that each bit in the array is used.

: 	void walk_bits_in_ulongs(
: 	    unsigned long const *base,
: 	    unsigned             nwords,
: 	    void (*f)(unsigned /*bitno*/, int /*bit*/)
: 	) {
: 	    unsigned bitno;
: 	    unsigned i;

: 	    for (bitno = 0, i = 0; i < nwords; i++) {
: 		unsigned long const word = base[i];
: 		unsigned long mask;

>>>             if (!word) continue;

: 		for (mask = 1; mask != 0; mask <<= 1, bitno++)
: 		    f(bitno, (word & mask) != 0);
: 	    }
: 	}

: Again, the saving comes about because we are NOT fetching bits in a
: true ELEMENT-WISE fashion, but in groups.

The above trick inserted (>>>) is a good one to remember when working
with bitsets.  On many CPUs, the above check is essentially 'free',
since it just depends on a condition flag that gets set when the value
is loaded anyway.

Intersection and union, of course, are very efficient (just use & and
|) in terms of bitsets.

Of course, you can do even better than that.  I timed a similar
algorithm on a wide variety of architectures, and the following
algorithm won for finding the set bit in a bitfield (or giving an
error if more than one is set):

static int get_single(unsigned int *, bv) {
    int i, res = -1;

    for (i = 0; i < NUM_BITVEC_INTS; i++) {
        if (bv[i]) { /* test 16 bits at a time! */
            if (res != -1) return -1;
	    res = i;
        }
    }
    if (res == -1) return res;

    i = bv[res];
    /* Binary search for the set bit, unrolled for speed. */
    if (i & 0x0000ffff) {
        if (i & 0xffff0000)
            return -1;
    } else {
        i >>= 16;
        res += 16;
    }

    if (i & 0x00ff) {
        if (i & 0xff00)
            return -1;
    } else {
        i >>= 8;
        res += 8;
    }
    
    if (i & 0x0f) {
        if (i & 0xf0)
            return -1;
    } else {
        i >>= 4;
        res += 4;
    }
    
    if (i & 0x3) {
        if (i & 0xc)
            return -1;
    } else {
        i >>= 2;
        res += 2;
    }
    
    if (i & 0x1) {
        if (i & 0x2)
            return -1;
	return res;
    } else {
        return res + 1;
    }
}

If you're wondering why the shifts are there, remember shifts are
cheap, and it turns out the full 32 bit integer constants (like
0xaaaaaaaa) appear to be rather slow on many RISC CPUs, so it's faster
to reduce the problem to one involving smaller constants.

Similar tricks for counting bits exist; I think the C FAQ has some of them.

---------------------------------------------------------------------------
Tim Hollebeek         | Disclaimer :=> Everything above is a true statement,
Electron Psychologist |                for sufficiently false values of true.
Princeton University  | email: tim@wfn-shop.princeton.edu
----------------------| http://wfn-shop.princeton.edu/~tim (NEW! IMPROVED!)
Technical Details
Message-ID: <4k60ec$acm@solutions.solon.com>
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail
References: <4jbciv$2kk@solutions.solon.com> <4jr741$h8l@solutions.solon.com> <4jttc7$3hu@solutions.solon.com> <4k1qp0$5n8@solutions.solon.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail
From: tim@franck.Princeton.EDU (telnet user)
Newsgroups: comp.lang.c.moderated
Subject: Re: Efficiency Question : bits vs. bytes (or anything else, for that matter)
Date: 6 Apr 1996 08:51:56 -0600
Organization: Princeton University
Sender: clc@solutions.solon.com
Approved: clc@solutions.solon.com
Message-ID: <4k60ec$acm@solutions.solon.com>
References: <4jbciv$2kk@solutions.solon.com> <4jr741$h8l@solutions.solon.com> <4jttc7$3hu@solutions.solon.com> <4k1qp0$5n8@solutions.solon.com>
Reply-To: tim@wagner.Princeton.EDU
NNTP-Posting-Host: solutions.solon.com
X-Newsreader: TIN [version 1.2 PL2]