Torvalds: More bitwise tricks
plus.google.com
plus.google.com
Here you have an exceedingly technical thread with some of OSS brightest minds working on a little puzzle and it's interspersed with litter. You have the sincere (yet misplaced) thank you for working on OSS, the clueless guy, and the isn't it cool we're talking about such hardcore topics guy. Every one of those comments makes me cringe a little.
This is why geeks have yet to give up mailing lists. The hurdle they put up is actually an effective barrier for the unmotivated. Some conversations are meant to be had in a quiet place amongst people who are similarly inclined. Google misleads you into thinking that Plus is that place, but it just isn't. Perhaps if there was a way for the community to sort the relevant from the irrelevant, it's just too tempting of a megaphone for people to jump in front of. Sometimes adding a little friction to the 'Post' button is a good thing.
The people who +1 stuff aren't the ones that understand the discussion, and the ones that do understand it don't +1, because why would they, it's obvious by reading the comments which ones are good and which ones are bad... It's a fantastic culture clash.
So either he doesn't care about the comments at all, or he is fishing for these exact pats on the back.
and as opposed to you I find this to be a nice thing for everyone++ to be invited to think Linus's question on Google+ (which is better than facebook or linked in or pinterest for this purpose)
'...so it's not a generic "count number of bits" (or even a generic "count number of bytes"). So I was hoping somebody would come up with something simple like (x & mask1) + (x&mask2)>>shift that just got the four possibilities right.'
But, I'm afraid you you've totally missed my point. What I don't love is the commentary being mixed in with the game. This is why when you have a panel discussion, you don't hand a microphone to everyone in the auditorium. When you go to a concert, you don't hand everyone an instrument. People have varying levels of contextual awareness and/or self control: it's not really their fault for throwing in their $0.02. I'm just pointing out that Google Plus is a type of forum and I'm still not sure what kind of conversation is supposed to go on there. This kind of discussion feels unnatural to me.
what linus does is more like an experiment, not on what g+ is but on what it can become. i pray the experiment will be successful, but i think i wont.
Google Plus was seeded with Google employees and they are the most enthusiastic users so it is filled with these kinds of discussions.
https://plus.google.com/102150693225130002912/posts/Uk1YxfFD...
no bytes: 00000000 -> 0
one byte: 000000ff -> 1
two bytes: 0000ffff -> 2
three bytes: 00ffffff -> 3
I think that is what he is trying to accomplish.So my quest to calculate the hash and the length of a pathname component efficiently continues. I'm pretty happy with where I am now (some changes to the code have happened, it you actually want to see the current situation you need to check out the kernel mailing list post), but finding the number of bytes in the final mask bothers me.
Using an explicit loop is out - the branch mispredicts kill it. And while at least modern Intel CPU's do quite well with just using the bit scan instructions ("bsf") to find where the first NUL or '/' was in the word, that sucks on some older CPU's.
So I came up with the following trick to count the number of bytes set in the byte mask:
/* Low bits set in each byte we used as a mask */
mask &= ONEBYTES;
/* Add up "mask + (mask<<8) + (mask<<16) +... ":
same as a multiply */
mask *= ONEBYTES;
/* High byte now contains count of bits set */
len += mask >> 8*(sizeof(unsigned long)-1);
and I'm wondering if anybody can come up with something that avoids the need for that multiply (and again - conditionals don't work, the mispredict costs kill you).Because that multiply isn't free either."
EDIT: Thanks for the tips, I'm new here
#define ONEBYTES 0x0101010101010101ul
The easiest solution is to indent the code by two spaces (HN renders it literally then).
static inline int f(const u64 m)
{
const u64 ones = 0x0101010101010101ULL;
const u64 b64 = m & ones;
const u32 b32 = b64 + (b64>>32);
const u16 b16 = b32 + (b32>>16);
const u8 b8 = b16 + (b16>> 8);
return b8;
} the simple shift+add version is all totally serialized
and nothing can be done before the previous operation
ends: as a result the three adds and three shifts will
inevitably take 6 cycles (the original P4 had that
double-pumped ALU, but not for shifts). That's already
slower than almost any multiply.
Edit: oops, I forgot your '(without multiplication)' qualifier. Yes, your way is likely the quickest without multiplication.I dont think he asked for this post to be put on the front page of HN, and he is probably laughing about it right now.
Next time you decide to #include <linus/stdflame.h>, please check to make sure it actually applies to the situation.
... give me a break.