digitalmars.D - std.intrinsic and bit arrays
- Munchgreeble bigfoot.com Nov 22 2005
- Sean Kelly <sean f4.ca> Nov 22 2005
- Munchgreeble <"a" b.com \"munchgreeble xATx bigfoot xDOTx com\"> Nov 23 2005
- Sean Kelly <sean f4.ca> Dec 03 2005
- "Regan Heath" <regan netwin.co.nz> Nov 22 2005
- Munchgreeble <"a" b.com \"munchgreeble xATx bigfoot xDOTx com\"> Nov 23 2005
- "Regan Heath" <regan netwin.co.nz> Nov 23 2005
- Derek Parnell <derek psych.ward> Nov 22 2005
- Ben Hinkle <Ben_member pathlink.com> Nov 22 2005
- Tiago Gasiba <tiago.gasiba gmail.com> Nov 23 2005
- Don Clugston <dac nospam.com.au> Nov 23 2005
- Don Clugston <dac nospam.com.au> Nov 23 2005
Wow. I am practically watering at the mouth. I've just discovered std.intrinsic Only the other day a colleague and I were debating what the best way was to find a bit in a bit array. Both of us lamenting that despite the fact that this problem comes up time and again in embedded code, you almost always end up doing a linear search - terribly inefficient when most processors have a dedicated instruction. Imagine my delight when just now I discovered D gives you access to the dedicated CPU instruction to do just that. I'm over the moon =) One thing I wasn't clear on though, how do these functions relate to bit arrays? Bit arrays seem like the obvious thing to use as arguments here - is it possible to use them instead? I was kind of hoping that bit arrays would provide a layer of abstraction on top of this stuff, whilst still allowing bit level operations. E.g. it would be nice to be able to do the below, instead of having to declare "bits" and "moreBits" as ints. bit[32] bits; bit[32] moreBits; : blah; : bits = bits ^ moreBits; but I can live without bit arrays if needs be - it would just have been a nice to have. Thanks =) Munch
Nov 22 2005
Munchgreeble bigfoot.com wrote:One thing I wasn't clear on though, how do these functions relate to bit arrays? Bit arrays seem like the obvious thing to use as arguments here - is it possible to use them instead? I was kind of hoping that bit arrays would provide a layer of abstraction on top of this stuff, whilst still allowing bit level operations. E.g. it would be nice to be able to do the below, instead of having to declare "bits" and "moreBits" as ints.
It's not an answer, but you can accomplish quite a bit via slicing and clever casting if you're willing to live some terrifying code: void main() { uint x = 99; bit[] b = cast(bit[])(cast(bit*)&x)[0..(x.sizeof*8)]; printf( "%u\n", b.length ); uint y = cast(uint)*&b[0]; printf( "%u\n", x ); printf( "%u\n", y ); for( int i = 7; i >= 0; --i ) printf( "%.*s", b[i] ? "1" : "0" ); printf( "\n" ); } Sean
Nov 22 2005
Wow, now that's what I call casting =) It would have taken me quite a long time to almost get to that stage, give up and post to the newsgroup, so thanks - much appreciated. It's not pretty I'll grant you, but you can usually encapsulate that stuff and cover it with comments, so I'm happy - thanks. One thing I'm not clear on - does the slicing cost anything at run time? I'm guessing not since all the limits are calculable at compile time? Regards Munch Sean Kelly wrote:Munchgreeble bigfoot.com wrote:One thing I wasn't clear on though, how do these functions relate to bit arrays? Bit arrays seem like the obvious thing to use as arguments here - is it possible to use them instead? I was kind of hoping that bit arrays would provide a layer of abstraction on top of this stuff, whilst still allowing bit level operations.
It's not an answer, but you can accomplish quite a bit via slicing and clever casting if you're willing to live some terrifying code: void main() { uint x = 99; bit[] b = cast(bit[])(cast(bit*)&x)[0..(x.sizeof*8)]; printf( "%u\n", b.length ); uint y = cast(uint)*&b[0]; printf( "%u\n", x ); printf( "%u\n", y ); for( int i = 7; i >= 0; --i ) printf( "%.*s", b[i] ? "1" : "0" ); printf( "\n" ); } Sean
Nov 23 2005
Munchgreeble wrote:Wow, now that's what I call casting =) It would have taken me quite a long time to almost get to that stage, give up and post to the newsgroup, so thanks - much appreciated. It's not pretty I'll grant you, but you can usually encapsulate that stuff and cover it with comments, so I'm happy - thanks. One thing I'm not clear on - does the slicing cost anything at run time? I'm guessing not since all the limits are calculable at compile time?
I suppose it depends how good the optimizer is. Might be worth compiling with -O and looking at the output. Sean
Dec 03 2005
On Tue, 22 Nov 2005 22:34:41 +0000 (UTC), <Munchgreeble bigfoot.com> wrote:Wow. I am practically watering at the mouth. I've just discovered std.intrinsic Only the other day a colleague and I were debating what the best way was to find a bit in a bit array. Both of us lamenting that despite the fact that this problem comes up time and again in embedded code, you almost always end up doing a linear search - terribly inefficient when most processors have a dedicated instruction. Imagine my delight when just now I discovered D gives you access to the dedicated CPU instruction to do just that. I'm over the moon =) One thing I wasn't clear on though, how do these functions relate to bit arrays? Bit arrays seem like the obvious thing to use as arguments here - is it possible to use them instead?
There are numerous posts on how bit arrays in D work, it seems people have a love/hate relationship with them, try a search you'll see what I mean.bit[32] bits; bit[32] moreBits; : blah; : bits = bits ^ moreBits;
I believe that once we get array operations the line above will be possible. Regan
Nov 22 2005
Regan Heath wrote:On Tue, 22 Nov 2005 22:34:41 +0000 (UTC), <Munchgreeble bigfoot.com> wrote:One thing I wasn't clear on though, how do these functions relate to bit arrays? Bit arrays seem like the obvious thing to use as arguments here - is it possible to use them instead?
There are numerous posts on how bit arrays in D work, it seems people have a love/hate relationship with them, try a search you'll see what I mean.
Thanks - a quick search for "bit array" was very informative. Actually I have to say that the archives are a mine of information. Everybody here in the newsgroup is so helpful and actually seems to dish out useful stuff. What a great place to be =)bit[32] bits; bit[32] moreBits; : blah; : bits = bits ^ moreBits;
I believe that once we get array operations the line above will be possible.
Ah yes - OK. Array operations sound great =) What I'm wondering is will the compiler (be able to) optimise such operations on bit arrays so that you don't end up with 32 separate XORs going on in the compiled code. Similarly, doing + on two bit arrays should just do a bitwise OR on each of the elements and multiply should turn into bitwise AND. I guess this is the kind of thing that's do-able? Cheers Munch
Nov 23 2005
On Wed, 23 Nov 2005 13:34:00 +0000, Munchgreeble <"a" b.com "munchgreeble xATx bigfoot xDOTx com"> wrote:bit[32] bits; bit[32] moreBits; : blah; : bits = bits ^ moreBits;
possible.
Ah yes - OK. Array operations sound great =) What I'm wondering is will the compiler (be able to) optimise such operations on bit arrays so that you don't end up with 32 separate XORs going on in the compiled code. Similarly, doing + on two bit arrays should just do a bitwise OR on each of the elements and multiply should turn into bitwise AND. I guess this is the kind of thing that's do-able?
I suspect so. In which case I think we just "wait and see". I don't think optimisations like those are high on the priority list, compared to other things. I suspect that they and things like them will eventually get done, if we give Walter the time and space to do them in. Regan
Nov 23 2005
On Tue, 22 Nov 2005 22:34:41 +0000 (UTC), Munchgreeble bigfoot.com wrote:Wow. I am practically watering at the mouth. I've just discovered std.intrinsic
I didn't realize it existed either. It's just what I needed too. I'd written a routine to read UTF text but needed to cater for endian-ness and bswap() is perfect for it. I'd done it the slow way with temporary variables :) -- Derek (skype: derek.j.parnell) Melbourne, Australia 23/11/2005 11:40:52 AM
Nov 22 2005
In article <1202ie2xfdynb.1jhc1jr4s9zi2$.dlg 40tude.net>, Derek Parnell says...On Tue, 22 Nov 2005 22:34:41 +0000 (UTC), Munchgreeble bigfoot.com wrote:Wow. I am practically watering at the mouth. I've just discovered std.intrinsic
I didn't realize it existed either. It's just what I needed too. I'd written a routine to read UTF text but needed to cater for endian-ness and bswap() is perfect for it. I'd done it the slow way with temporary variables :)
FWIW, std.stream.EndianStream could save you some trouble. It uses bswap, too. Check out std.stream.EndianStream.fixBO (where BO stands for byte-order not body-odour) for an endian-fixing routine that works for more than just 32 bits words.
Nov 22 2005
Munchgreeble bigfoot.com schrieb:Wow. I am practically watering at the mouth. I've just discovered std.intrinsic Only the other day a colleague and I were debating what the best way was to find a bit in a bit array. Both of us lamenting that despite the fact that this problem comes up time and again in embedded code, you almost always end up doing a linear search - terribly inefficient when most processors have a dedicated instruction. Imagine my delight when just now I discovered D gives you access to the dedicated CPU instruction to do just that. I'm over the moon =)
Wow!!! Me too! I'm speechless... Amazing! Thanks for posting this message - you've opened my eyes! :) Now (forgive my ignorance) I feel that I must ask the following: If there are functions to find/set/reset bits, is there any function to count bits? For example, how can I do this efficiently: ulong x = 0x1234; // whatever... bitcount(x) -> 5; // there are 5 ones in x Thanks, Tiago -- Tiago Gasiba (M.Sc.) - http://www.gasiba.de Everything should be made as simple as possible, but not simpler.
Nov 23 2005
Tiago Gasiba wrote:Munchgreeble bigfoot.com schrieb:Wow. I am practically watering at the mouth. I've just discovered std.intrinsic Only the other day a colleague and I were debating what the best way was to find a bit in a bit array. Both of us lamenting that despite the fact that this problem comes up time and again in embedded code, you almost always end up doing a linear search - terribly inefficient when most processors have a dedicated instruction. Imagine my delight when just now I discovered D gives you access to the dedicated CPU instruction to do just that. I'm over the moon =)
Wow!!! Me too! I'm speechless... Amazing! Thanks for posting this message - you've opened my eyes! :) Now (forgive my ignorance) I feel that I must ask the following: If there are functions to find/set/reset bits, is there any function to count bits? For example, how can I do this efficiently: ulong x = 0x1234; // whatever... bitcount(x) -> 5; // there are 5 ones in x
That should be a standard function too. There's no instrinsic for it, though, because x86 has no instruction for that (some other CPUs do, though, it's typically called "population count" or POPC -- stupid name, bitcount is much better). You add neighbouring bits, then add neighbouring pairs, nibbles, bytes, and words: // Calculates the number of set bits in a 32-bit integer. int bitcount(uint x) { // add neighbouring bits. Each bit is 0 or 1. x = ((x&0xAAAAAAAA)>>1) +(x&0x55555555); // now each two bits of x is a number 00,01 or 10. // now add neighbouring pairs x = ((x&0xCCCCCCCC)>>2) + (x&0x33333333); // now each nibble holds 0000-0100. Adding them wont // overflow any more, so we don't need to mask any more // Now add the nibbles x += (x>>4); // each byte is a number from 00000000 to 00001000. // now add the bytes x += (x>>8); // now add the words x += (x>>16); return x; } Nifty, eh? On paper, it doesn't look as fast as a table lookup, but it adds 4 bytes at once, and it has no cache problems, so in real problems it should be faster. (Note that if you do a simple speed test, a table lookup will look deceptively good because the table will stay in the cache. You need to profile a realistic program). I did not make it up, I read it on a newsgroup long ago. But I recreated it from memory, so it's completely public domain. I have a few of these bit functions (all in C++), I should convert them to D and submit them to Phobos. Especially since they even have unit tests -- a rarity for my C++ code :-)
Nov 23 2005
Don Clugston wrote:I have a few of these bit functions (all in C++), I should convert them to D and submit them to Phobos. Especially since they even have unit tests -- a rarity for my C++ code :-)
I just put them into MathExtra on dsource.org. Not that they belong there, but anyway...
Nov 23 2005
Great! And thanks for posting the algorithm - I must confess I've always used a 16-bit wide table lookup for bit counting. Cheers Munch Don Clugston wrote:Don Clugston wrote:I have a few of these bit functions (all in C++), I should convert them to D and submit them to Phobos. Especially since they even have unit tests -- a rarity for my C++ code :-)
I just put them into MathExtra on dsource.org. Not that they belong there, but anyway...
Nov 23 2005









Sean Kelly <sean f4.ca> 