Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

_BitScanForward in C#?

Tags:

c++

c#

.net

pinvoke

I am translating a program written in C++ to C#, and I have come across an intrinsic function that I cannot work around. In C++ this is known as:

unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask);

If I only knew what DLL, if any, the intrinsic functions were in, I could use P/Invoke. Since I do not know, I looked for alternatives in the .NET framework, but I have come up empty handed.

Does anyone know how use P/Invoke on _BitScanForward, or an .NET method that does the same thing?

Any help is appreciated, thank you.

like image 585
SvalinnAsgard Avatar asked Feb 01 '12 02:02

SvalinnAsgard


People also ask

What is a bitscan?

a function that determines the bit-index of the least significant 1 bit (LS1B) or the most significant 1 bit (MS1B) in an integer such as bitboards. If exactly one bit is set in an unsigned integer, representing a numerical value of a power of two, this is equivalent to a base-2 logarithm.

What is bit scan forward?

Description. bsf scans the bits, starting at bit 0, in the doubleword operand or the second word. If the bits are all zero, ZF is cleared. Otherwise, ZF is set and the bit index of the first set bit, found while scanning in the forward direction, is loaded into the destination register.


4 Answers

Intrinsic functions aren't in any library, they're implemented inside the CPU, the compiler emits the machine code which the CPU recognizes as evoking this particular behavior.

They're a way of getting access to instructions that don't have a simple C equivalent.

Until the .NET optimizer becomes smart enough to recognize them (for example, the Mono JIT recognizes some SIMD instructions, encoded in MSIL as calls to functions of a particular class, similarly the .NET JIT replaces calls to System.Math methods with floating-point operations), your C# code is doomed to run an order of magnitude slower than the original C++.

like image 148
Ben Voigt Avatar answered Sep 29 '22 11:09

Ben Voigt


The _BitScanForward C++ function is an intrinsic compiler function. It finds the first on bit in a sequence of bytes searching from the lowest order bit to the highest and returning the value of the bit. You could probably implement something similar using bit manipulation tactics in C# (though it'll never come close to the same performance). If you're comfortable with bit manipulation in C++ then its basically the same in C#.

like image 21
M.Babcock Avatar answered Sep 29 '22 11:09

M.Babcock


_BitScanForward searches for the first set bit in an integer, starting from the least significant bit searching towards the most significant bit. It compiles to the bsf instruction on the x86 platform.

The bit twiddling hacks page includes a handful of potential replacement algorithms that excel in different situations. There's an O(N) function (that half the time with uniformly-distributed inputs returns with only one iteration) and some sub-linear options, and some that make use of multiplication steps. Picking one might not be trivial, but any should work.

like image 20
sarnold Avatar answered Sep 29 '22 11:09

sarnold


It is not possible to P/Invoke _BitScanForward because it is a compiler intrinsic, not an actual library function (it gets translated by the Visual C++ compiler to a BSF x86 machine instruction). As far as I'm aware, there is no MSIL instruction for this "find first set" operation. The simplest thing to do is write your own C++ native DLL that exports a function that invokes _BitScanForward(), and then P/Invoke that.

You can also write it directly in C# using bit manipulation (see Algorithms for find first set in Wikipedia). I'm not sure if this would be faster or slower than P/Invoke. Measure and find out.

like image 28
Chiara Coetzee Avatar answered Sep 29 '22 13:09

Chiara Coetzee