Open alexrp opened 3 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Tagging subscribers to this area: @tannergooding, @pgovind See info in area-owners.md if you want to be subscribed.
Author: | alexrp |
---|---|
Assignees: | - |
Labels: | `api-suggestion`, `area-System.Numerics`, `untriaged` |
Milestone: | - |
Just my two cents, I would much rather write a & ~b
than BitOperations.AndNot(a, b)
. That really seems like something the JIT should be optimizing on the dev's behalf based on the current machine's capabilities.
I agree. Particularly for simple arithmetic like a & ~b
where there is basically one way to right it, I think the JIT recognizing and optimizing the expression is better.
It would be good to restrict BitOperations to more complex cases where the patterns are many or particularly complex, such as Rotate
or http://graphics.stanford.edu/~seander/bithacks.html
I recall Erlang has a special type for working with bits. Do we need something like that in .Net? This api is good but still you have to do it manually. A special syntax/model would be cleaner I guess. Here is the thing I'm talking about: https://erlang.org/doc/programming_examples/bit_syntax.html
Just my two cents, I would much rather write
a & ~b
thanBitOperations.AndNot(a, b)
. That really seems like something the JIT should be optimizing on the dev's behalf based on the current machine's capabilities.
No objections from me there. In fact, I'm going to scrap the AndNot
part of this proposal anyway because further investigation on my end revealed what should probably have been obvious: It severely inhibits the JIT's ability to do even simple optimizations like constant folding to the point where there's probably no gain to be had from using it manually.
I recall Erlang has a special type for working with bits. Do we need something like that in .Net? This api is good but still you have to do it manually. A special syntax/model would be cleaner I guess. Here is the thing I'm talking about: https://erlang.org/doc/programming_examples/bit_syntax.html
There is a discussion over on csharplang for something along the lines of that, though it's more like C bit fields than Erlang bit syntax: https://github.com/dotnet/csharplang/discussions/465
Regardless, it would be good to have these primitives in place.
@tannergooding what do you think about the API as currently proposed?
@alexrp:
Field
. I think ConsecutiveBits
or similar (something containing Bits
) would be clearerDeposit
. Insert
or Replace
are the terms that immediately come to mind as alternativesnint
/nuint
overloads at the same time.I've updated the API shape per our discussion on Discord.
What needs to happen next to move this forward?
Background and Motivation
When dealing with low-level file formats, network protocols, instruction encodings, and other such things, it's common to need to extract and deposit bit fields of various sizes. Writing generic versions of these operations (i.e. without a constant mask) can be fairly error-prone. Also, there is room for exploiting certain architecture-specific intrinsics (e.g. x86 BMI) similar to what the current methods on
BitOperations
do.Proposed API
(I'm not necessarily married to these method names.)
Acceptable
count
ValuesA design choice has to be made with regards to
count=0
andcount=32
(foruint
) /count=64
(forulong
). You generally only get to support one or the other in branchless code. There are 4 options that I see:count=0
properly.count=32
/count=64
properly.I think (4) is probably a non-starter, at least until the JIT gets full
cmov
support. Between the other 3 options, I have no strong preference, but would probably lean towards (3) for no particular reason other than it feels right and it's what other projects do. (I can't think of any real use cases for such 'weird'count
values anyway.)Usage Examples
One of my projects is full of code looking like this:
Alternative Designs
The API proposed here is loosely based on the functions in QEMU: https://git.qemu.org/?p=qemu.git;a=blob;f=include/qemu/bitops.h;h=3acbf3384c63ce4f7d2a98db962ae999de3b2b63;hb=HEAD
Risks
None?
Potential Implementation
A basic implementation could look something like this:
(This implementation chooses option (3) for
count
values.)