Dov
Dov

Reputation: 8570

high speed swapping 4 bits within word

The following code will take 4-bit "nibbles" and swap them:

inline void swap(uint64_t& v, int pos1, int pos2) {
    pos1 <<= 2; pos2 <<= 2;
    uint64_t t1 = v & (0xFLL << pos1);
    uint64_t t2 = v & (0xFLL << pos2);
    cout << hex << t1 <<',' << t2 << '\n';
    v &= ~(t1 | t2);
    int deltaBitPos = pos1 - pos2;
    if (deltaBitPos > 0) {
        t2 <<= deltaBitPos;
        t1 >>= deltaBitPos;
    } else {
        deltaBitPos = -deltaBitPos;
        t2 >>= deltaBitPos;
        t1 <<= deltaBitPos;
    }
    v |= (t1 | t2);
}

For example:

uint64_t v = 0x123456789LL;  
swap(v, 0, 1)

will result in v = 0x123456798

But is there a faster way with some bitwise primitive functions? I can't find any that will do it, either the gcc builtins, or on bithacks:

https://graphics.stanford.edu/~seander/bithacks.html

Upvotes: 2

Views: 108

Answers (1)

Matt Timmermans
Matt Timmermans

Reputation: 59358

It's not bad, but I would get rid of the conditional and simplify a bit:

inline void swap(uint64_t& v, int pos1, int pos2) {
    pos1 <<= 2; pos2 <<= 2;
    uint64_t ret = v&~((0xFLL << pos1)|(0xFLL << pos2));
    ret|=((v>>pos1)&15)<<pos2;
    ret|=((v>>pos2)&15)<<pos1;
    v = ret;
}

Upvotes: 4

Related Questions