Looking for intrinsic "least significant bit" on Visual Studio

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

OliverBr
Posts: 725
Joined: Tue Dec 18, 2007 9:38 pm
Location: Munich, Germany
Full name: Dr. Oliver Brausch

Looking for intrinsic "least significant bit" on Visual Studio

Post by OliverBr »

Hello,
For gcc/clang both intrinsic functions are available for most and least significant bit (leading/trailing zeros):

Code: Select all

__builtin_clz 
__builtin_ctz
For Visual Studio 2019 I have found an intrinsic function for most significant bit (leading zeros)

Code: Select all

__lzcnt64
A function named "__tzcnt64" doesn't exist. (trailing zeros)

Is there a function to get LSB in Visual Studio?
Chess Engine OliThink: http://brausch.org/home/chess
OliThink GitHub:https://github.com/olithink
User avatar
towforce
Posts: 11558
Joined: Thu Mar 09, 2006 12:57 am
Location: Birmingham UK

Re: Looking for intrinsic "least significant bit" on Visual Studio

Post by towforce »

It looks like a language issue rather than visual studio. In C derived languages, it's normally something like:

b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);



etc.

Basically 0 != (v & Math.Pow(2, bitnumber))
Writing is the antidote to confusion.
It's not "how smart you are", it's "how are you smart".
Your brain doesn't work the way you want, so train it!
OliverBr
Posts: 725
Joined: Tue Dec 18, 2007 9:38 pm
Location: Munich, Germany
Full name: Dr. Oliver Brausch

Re: Looking for intrinsic "least significant bit" on Visual Studio

Post by OliverBr »

towforce wrote: Thu Sep 03, 2020 3:54 pm It looks like a language issue rather than visual studio. In C derived languages, it's normally something like:

b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);



etc.

Basically 0 != (v & Math.Pow(2, bitnumber))
I fear you haven't got my question correctly.

My issue is not a language issue, it is really a compiler issue:

1) I have already working methods in language C to get the least significant bit.
2) In order to improve performance I am looking for an intrinsic function which is compiler dependent.
3) In gcc there are two functions,
4) In Visual Studio I have just found one.
5) I am looking for the second intrinsic function in Visual Studio other than "__lzcnt64"
Chess Engine OliThink: http://brausch.org/home/chess
OliThink GitHub:https://github.com/olithink
mar
Posts: 2554
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Looking for intrinsic "least significant bit" on Visual Studio

Post by mar »

this is not exactly the same but you may be looking for _BitscanForward64 and _BitscanReverse64, which translate to bsf/bsr x86 instructions
I believe __lzcnt64 is available on relatively new machines only
bsf/bsr both return the index of the least (forward) or most (reverse) bit, but is undefined for zero, so you should explicitly check for 0 yourself
Martin Sedlak
chrisw
Posts: 4313
Joined: Tue Apr 03, 2012 4:28 pm

Re: Looking for intrinsic "least significant bit" on Visual Studio

Post by chrisw »

mar wrote: Thu Sep 03, 2020 4:52 pm this is not exactly the same but you may be looking for _BitscanForward64 and _BitscanReverse64, which translate to bsf/bsr x86 instructions
I believe __lzcnt64 is available on relatively new machines only
bsf/bsr both return the index of the least (forward) or most (reverse) bit, but is undefined for zero, so you should explicitly check for 0 yourself
If I remember correct from 1997, we were using beta dev version of what became Visual Studio and CSTal had the asm instruction in some sort of macro. I’ll look up what I do now when I get home, but am fairly sure there’s a standard fast way that works, may well be the Mar instructions above, and I do think you indeed have to check you’re giving them non zero data.

Btw, are you compiling SF NNUE in VS, I got stuck on compile errors demanding c++17 support?
OliverBr
Posts: 725
Joined: Tue Dec 18, 2007 9:38 pm
Location: Munich, Germany
Full name: Dr. Oliver Brausch

Re: Looking for intrinsic "least significant bit" on Visual Studio

Post by OliverBr »

mar wrote: Thu Sep 03, 2020 4:52 pm this is not exactly the same but you may be looking for _BitscanForward64 and _BitscanReverse64, which translate to bsf/bsr x86 instructions
I believe __lzcnt64 is available on relatively new machines only
bsf/bsr both return the index of the least (forward) or most (reverse) bit, but is undefined for zero, so you should explicitly check for 0 yourself
Thank you. _BitscanForward64 helps me a bit, even it is not as fast as __lzcnt64. (< 10% gain)

I still don't get, why there is no "__tzcnt64" in Visual Studio, as the processors that support "lzcnt" do automatically support "tzcnt".
See also:
https://www.felixcloutier.com/x86/lzcnt
https://www.felixcloutier.com/x86/tzcnt

Again, gcc/clang do support both commands. I get great results in Linux and MacOSX. (> 20% gain)
Last edited by OliverBr on Thu Sep 03, 2020 6:17 pm, edited 1 time in total.
Chess Engine OliThink: http://brausch.org/home/chess
OliThink GitHub:https://github.com/olithink
User avatar
towforce
Posts: 11558
Joined: Thu Mar 09, 2006 12:57 am
Location: Birmingham UK

Re: Looking for intrinsic "least significant bit" on Visual Studio

Post by towforce »

chrisw wrote: Thu Sep 03, 2020 5:56 pmBtw, are you compiling SF NNUE in VS, I got stuck on compile errors demanding c++17 support?

Some projects require the C++ redistributable. If so, you can get it here.
Writing is the antidote to confusion.
It's not "how smart you are", it's "how are you smart".
Your brain doesn't work the way you want, so train it!
OliverBr
Posts: 725
Joined: Tue Dec 18, 2007 9:38 pm
Location: Munich, Germany
Full name: Dr. Oliver Brausch

Re: Looking for intrinsic "least significant bit" on Visual Studio

Post by OliverBr »

chrisw wrote: Thu Sep 03, 2020 5:56 pm If I remember correct from 1997, we were using beta dev version of what became Visual Studio and CSTal had the asm instruction in some sort of macro. I’ll look up what I do now when I get home, but am fairly sure there’s a standard fast way that works, may well be the Mar instructions above, and I do think you indeed have to check you’re giving them non zero data.
An asm code snippet for Visual Studio would be very helpful. This is the machine command:
https://www.felixcloutier.com/x86/tzcnt

(the parameter is never 0)
Btw, are you compiling SF NNUE in VS, I got stuck on compile errors demanding c++17 support?
No, I am developing OliThink572 using "tzcnt" and looking for a solution for my Windows executables. _BitscanForward64 works, but is slower.
Chess Engine OliThink: http://brausch.org/home/chess
OliThink GitHub:https://github.com/olithink
Gerd Isenberg
Posts: 2250
Joined: Wed Mar 08, 2006 8:47 pm
Location: Hattingen, Germany

Re: Looking for intrinsic "least significant bit" on Visual Studio

Post by Gerd Isenberg »

OliverBr wrote: Thu Sep 03, 2020 3:43 pm Hello,
For gcc/clang both intrinsic functions are available for most and least significant bit (leading/trailing zeros):

Code: Select all

__builtin_clz 
__builtin_ctz
For Visual Studio 2019 I have found an intrinsic function for most significant bit (leading zeros)

Code: Select all

__lzcnt64
A function named "__tzcnt64" doesn't exist. (trailing zeros)

Is there a function to get LSB in Visual Studio?
Maybe this helps
https://developercommunity.visualstudio ... clang.html
https://github.com/gcc-mirror/gcc/blob/ ... miintrin.h
Gerd Isenberg
Posts: 2250
Joined: Wed Mar 08, 2006 8:47 pm
Location: Hattingen, Germany

Re: Looking for intrinsic "least significant bit" on Visual Studio

Post by Gerd Isenberg »

OliverBr wrote: Thu Sep 03, 2020 6:15 pm
I still don't get, why there is no "__tzcnt64" in Visual Studio, as the processors that support "lzcnt" do automatically support "tzcnt".
See also:
https://www.felixcloutier.com/x86/lzcnt
https://www.felixcloutier.com/x86/tzcnt

Again, gcc/clang do support both commands. I get great results in Linux and MacOSX. (> 20% gain)
The reason might be that AMD's Advanced Bit Manipulation had only _lzcnt64, and trailing zero count came later with Intel's BMI1.