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: 11678
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))
The simple reveals itself after the complex has been exhausted.
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: 2569
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
chrisw
Posts: 4346
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: 11678
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.
The simple reveals itself after the complex has been exhausted.
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.