Ignore:
Timestamp:
Oct 21, 2011, 6:28:09 PM (8 years ago)
Author:
ksherdy
Message:

Prefer static function overloading on bitblock128_t types for performance. Methods templated on BitBlock? type do not inline efficiently.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/bitblock128.hpp

    r1527 r1542  
    1212#define BITBLOCK128_HPP_
    1313
    14 #include "idisa128.hpp"
     14static IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, bitblock128_t & carry, bitblock128_t & sum);
     15static IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, bitblock128_t & borrow, bitblock128_t & difference);
     16static IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, bitblock128_t & carry, bitblock128_t & rslt);
     17static IDISA_ALWAYS_INLINE bool bitblock_has_bit(bitblock128_t arg1);
     18static IDISA_ALWAYS_INLINE uint64_t bitblock_bit_count(bitblock128_t arg1);
     19static IDISA_ALWAYS_INLINE void signbitmask(bitblock128_t & v);
     20static IDISA_ALWAYS_INLINE bitblock128_t convert (uint64_t s);
     21static IDISA_ALWAYS_INLINE uint64_t convert (bitblock128_t v);
     22
     23IDISA_ALWAYS_INLINE void adc(bitblock128_t x, bitblock128_t y, bitblock128_t & carry, bitblock128_t & sum)
     24{
     25        bitblock128_t gen = simd_and(x, y);
     26        bitblock128_t prop = simd_or(x, y);
     27        bitblock128_t partial = simd<64>::add(simd<64>::add(x, y), carry);
     28        bitblock128_t c1 = simd128<128>::slli<64>(simd<64>::srli<63>(simd_or(gen, simd_andc(prop, partial))));
     29        sum = simd<64>::add(c1, partial);
     30        // carry = simd_and(hibitmask<bitblock128_t>(), simd_or(gen, simd_andc(prop, sum))); // TODO - set high bit carry via hibitmask
     31        carry = simd128<128>::srli<127>(simd_or(gen, simd_andc(prop, sum))); // TODO -
     32}
     33
     34IDISA_ALWAYS_INLINE void sbb(bitblock128_t x, bitblock128_t y, bitblock128_t & borrow, bitblock128_t & difference)
     35{
     36        bitblock128_t gen = simd_andc(y, x);
     37        bitblock128_t prop = simd_not(simd_xor(x, y));
     38        bitblock128_t partial = simd<64>::sub(simd<64>::sub(x, y), borrow);
     39        bitblock128_t b1 = simd128<128>::slli<64>(simd<64>::srli<63>(simd_or(gen, simd_and(prop, partial))));
     40        difference = simd<64>::sub(partial, b1);
     41        // borrow = simd_and(hibitmask<bitblock128_t>, simd_or(gen, simd_and(prop, difference))); // TODO - set high bit carry via hibitmask
     42        borrow = simd128<128>::srli<127>(simd_or(gen, simd_and(prop, difference)));
     43}
     44
     45IDISA_ALWAYS_INLINE void advance_with_carry(bitblock128_t cursor, bitblock128_t & carry, bitblock128_t & rslt)
     46{
     47bitblock128_t shift_out = simd<64>::srli<63>(cursor);
     48bitblock128_t low_bits = esimd<64>::mergel(shift_out, carry);
     49// carry = simd_and(hibitmask<bitblock128_t>, cursor);
     50carry = simd128<128>::srli<64>(shift_out);                                              // carry - accumlated 127 shift right locical shift of cursor
     51rslt = simd_or(simd<64>::add(cursor, cursor), low_bits);
     52}
     53
     54IDISA_ALWAYS_INLINE bool bitblock_has_bit(bitblock128_t arg1)
     55{
     56        // TOOD simd128::any(arg1);
     57        return bitblock::any(arg1);
     58}
     59
     60IDISA_ALWAYS_INLINE uint64_t bitblock_bit_count(bitblock128_t arg1)
     61{
     62        // TODO simd128::popcount(arg1)
     63        return mvmd<64>::extract<0>(simd128<128>::popcount(arg1));
     64}
     65
     66IDISA_ALWAYS_INLINE void signbitmask(bitblock128_t & v)
     67{
     68        // TODO simd128::
     69        v =  simd128<128>::slli<127>(simd128<128>::constant<1>());
     70}
     71
     72/* Type conversion support */
     73union ubitblock128 {
     74        //bitblock256_t 256;
     75        bitblock128_t _128;
     76        uint64_t _64[sizeof(bitblock128_t)/sizeof(uint64_t)];
     77        uint32_t _32[sizeof(bitblock128_t)/sizeof(uint32_t)];
     78        uint16_t _16[sizeof(bitblock128_t)/sizeof(uint16_t)];
     79        uint8_t _8[sizeof(bitblock128_t)/sizeof(uint8_t)];
     80};
     81
     82IDISA_ALWAYS_INLINE bitblock128_t convert(uint64_t s)
     83{
     84        ubitblock128 b = {b._128 = simd128<128>::constant<0>()}; // = {0};
     85        b._64[0] = s;
     86        return b._128;
     87}
     88
     89IDISA_ALWAYS_INLINE uint64_t convert (bitblock128_t v)
     90{
     91        return (uint64_t) mvmd<64>::extract<0>(v);
     92}
     93
    1594
    1695#endif /* BITBLOCK128_HPP_ */
Note: See TracChangeset for help on using the changeset viewer.