Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add bitreverse function #34791

Merged
merged 1 commit into from
Feb 20, 2020
Merged

add bitreverse function #34791

merged 1 commit into from
Feb 20, 2020

Conversation

JeffBezanson
Copy link
Member

This can be useful for parsing binary formats, and generally helps round out the set of bit-level operations.

base/int.jl Outdated

function bitreverse(x::Union{Int8,UInt8})
z = x % UInt8
z = ((z >>> 1) & 0x55) | ((z << 1) & 0xaa)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the mix of arithmetic and logic shifts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no <<<?

base/int.jl Outdated
Comment on lines 893 to 897
z = x % UInt16
z = ((z >>> 1) & 0x5555) | ((z << 1) & 0xaaaa)
z = ((z >>> 2) & 0x3333) | ((z << 2) & 0xcccc)
z = ((z >>> 4) & 0x0f0f) | ((z << 4) & 0xf0f0)
z = ((z >>> 8) & 0x00ff) | ((z << 8) & 0xff00)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry to jump in, but why not use bswap for some of these operations? It's shorter, easier to understand, less reliant on magic numbers, and presumably compiles to efficient LLVM.

Copy link
Contributor

@jakobnissen jakobnissen Feb 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, one could use a single method for all ints, like this:

function bitreverse1(x::Base.BitInteger)
    z = unsigned(x)
    mask1 = 0x55555555555555555555555555555555 % typeof(z)
    mask2 = 0x33333333333333333333333333333333 % typeof(z)
    mask4 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f % typeof(z)
    z = ((z & mask1) << 1) | ((z >> 1) & mask1)
    z = ((z & mask2) << 2) | ((z >> 2) & mask2)
    z = ((z & mask4) << 4) | ((z >> 4) & mask4)
    return bswap(z) % typeof(x)
end

On my machine, this generates more efficient code, too, but I don't know if it uses too much "compile time magic".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, LLVM already has a bitreverse intrinsic: https://llvm.org/docs/LangRef.html#llvm-bitreverse-intrinsics. But it will probably compile to the same thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But with the intrinsic, it's (more) not our problem to make sure it's fast on all the architectures.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll use this implementation, since adding intrinsics is harder and I'd rather avoid llvmcall.

@JeffBezanson JeffBezanson force-pushed the jb/bitreverse branch 2 times, most recently from cf621b1 to 627b7d2 Compare February 18, 2020 16:28
@JeffBezanson JeffBezanson changed the title RFC: add bitreverse function add bitreverse function Feb 18, 2020
@JeffBezanson JeffBezanson added the triage This should be discussed on a triage call label Feb 18, 2020
@JeffBezanson JeffBezanson merged commit fb301f4 into master Feb 20, 2020
@JeffBezanson JeffBezanson deleted the jb/bitreverse branch February 20, 2020 19:33
@JeffBezanson JeffBezanson removed the triage This should be discussed on a triage call label Feb 20, 2020
birm pushed a commit to birm/julia that referenced this pull request Feb 22, 2020
KristofferC pushed a commit that referenced this pull request Apr 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants