Changeset d0c804297259976d08303935ebc0332aec812118

Show
Ignore:
Timestamp:
05/01/08 15:21:03 (8 months ago)
Author:
krayouva <krayouva@…>
Parents:
1bc545c8942b47e034f824644b4834a991178afc
Children:
208885f7930551213d294117aa06fa7ebb1cf8b1
git-committer:
krayouva <krayouva@gmail.com> / 2008-05-01T01:21:03Z-0400
Message:

* Inlined bitwise vector operations + added benchmarks

Location:
c
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • c/benchmark/bm_bitvector.c

    rfded01 rd0c804  
    3636} 
    3737 
     38static void cpp_bs_and_sparse() 
     39{ 
     40    std::bitset<SCAN_SIZE> *_bs = new std::bitset<SCAN_SIZE>(bs); 
     41    *_bs &= bs; 
     42    delete _bs; 
     43} 
     44static void cpp_bs_or_sparse() 
     45{ 
     46    std::bitset<SCAN_SIZE> *_bs = new std::bitset<SCAN_SIZE>(bs); 
     47    *_bs |= bs; 
     48    delete _bs; 
     49} 
     50static void cpp_bs_xor_sparse() 
     51{ 
     52    std::bitset<SCAN_SIZE> *_bs = new std::bitset<SCAN_SIZE>(bs); 
     53    *_bs ^= bs; 
     54    delete _bs; 
     55} 
     56static void cpp_bs_not_sparse() 
     57{ 
     58    std::bitset<SCAN_SIZE> *_bs = new std::bitset<SCAN_SIZE>(bs); 
     59    _bs->flip(); 
     60    delete _bs; 
     61} 
     62static void cpp_bs_and_dense() 
     63{ 
     64    cpp_bs_and_sparse(); 
     65} 
     66static void cpp_bs_or_dense() 
     67{ 
     68    cpp_bs_or_sparse(); 
     69} 
     70static void cpp_bs_xor_dense() 
     71{ 
     72    cpp_bs_xor_sparse(); 
     73} 
     74static void cpp_bs_not_dense() 
     75{ 
     76    cpp_bs_not_sparse(); 
     77} 
     78 
    3879static void cpp_bs_set_dense() 
    3980{ 
     
    72113} 
    73114 
     115static void ferret_bv_and_sparse() 
     116{ 
     117    FrtBitVector * _bv = frt_bv_and(bv, bv); 
     118    free(_bv); 
     119} 
     120static void ferret_bv_or_sparse() 
     121{ 
     122    FrtBitVector * _bv = frt_bv_or(bv, bv); 
     123    free(_bv); 
     124} 
     125static void ferret_bv_xor_sparse() 
     126{ 
     127    FrtBitVector * _bv = frt_bv_xor(bv, bv); 
     128    free(_bv); 
     129} 
     130static void ferret_bv_not_sparse() 
     131{ 
     132    FrtBitVector * _bv = frt_bv_not(bv); 
     133    free(_bv); 
     134} 
     135static void ferret_bv_and_dense() 
     136{ 
     137    ferret_bv_and_sparse(); 
     138} 
     139static void ferret_bv_or_dense() 
     140{ 
     141    ferret_bv_or_sparse(); 
     142} 
     143static void ferret_bv_xor_dense() 
     144{ 
     145    ferret_bv_xor_sparse(); 
     146} 
     147static void ferret_bv_not_dense() 
     148{ 
     149    ferret_bv_not_sparse(); 
     150} 
     151 
    74152static void ferret_bv_set_sparse() 
    75153{ 
     
    124202    BM_ADD(cpp_bs_set_sparse); 
    125203    BM_ADD(cpp_bs_scan_sparse); 
     204    BM_ADD(cpp_bs_and_sparse); 
     205    BM_ADD(cpp_bs_or_sparse); 
     206    BM_ADD(cpp_bs_not_sparse); 
     207    BM_ADD(cpp_bs_xor_sparse); 
     208 
    126209    BM_ADD(cpp_bs_set_dense); 
    127210    BM_ADD(cpp_bs_scan_dense); 
     211    BM_ADD(cpp_bs_and_dense); 
     212    BM_ADD(cpp_bs_or_dense); 
     213    BM_ADD(cpp_bs_not_dense); 
     214    BM_ADD(cpp_bs_xor_dense); 
    128215#endif 
    129216    BM_ADD(ferret_bv_set_sparse); 
    130217    BM_ADD(ferret_bv_scan_sparse); 
     218    BM_ADD(ferret_bv_and_sparse); 
     219    BM_ADD(ferret_bv_or_sparse); 
     220    BM_ADD(ferret_bv_not_sparse); 
     221    BM_ADD(ferret_bv_xor_sparse); 
     222 
    131223    BM_ADD(ferret_bv_set_dense); 
    132224    BM_ADD(ferret_bv_scan_dense); 
     225    BM_ADD(ferret_bv_and_dense); 
     226    BM_ADD(ferret_bv_or_dense); 
     227    BM_ADD(ferret_bv_not_dense); 
     228    BM_ADD(ferret_bv_xor_dense); 
    133229    BM_TEARDOWN(teardown); 
    134230} 
  • c/include/bitvector.h

    red4cf5 rd0c804  
    218218 *   set 
    219219 */ 
    220 extern int frt_bv_recount(FrtBitVector *bv); 
     220extern FRT_ATTR_ALWAYS_INLINE 
     221int frt_bv_recount(FrtBitVector *bv) 
     222{ 
     223    unsigned int extra = ((bv->size & 31) >> 3) + 1; 
     224    unsigned int len   = bv->size >> 5; 
     225    unsigned int idx, count = 0; 
     226 
     227    if (bv->extends_as_ones) { 
     228        for (idx = 0; idx < len; ++idx) { 
     229            count += frt_count_zeros(bv->bits[idx]); 
     230        } 
     231        switch (extra) { 
     232            case 4: count += frt_count_zeros(bv->bits[idx] | 0x00ffffff); 
     233            case 3: count += frt_count_zeros(bv->bits[idx] | 0xff00ffff); 
     234            case 2: count += frt_count_zeros(bv->bits[idx] | 0xffff00ff); 
     235            case 1: count += frt_count_zeros(bv->bits[idx] | 0xffffff00); 
     236        } 
     237    } 
     238    else { 
     239        for (idx = 0; idx < len; ++idx) { 
     240            count += frt_count_ones(bv->bits[idx]); 
     241        } 
     242        switch (extra) { 
     243            case 4: count += frt_count_ones(bv->bits[idx] & 0xff000000); 
     244            case 3: count += frt_count_ones(bv->bits[idx] & 0x00ff0000); 
     245            case 2: count += frt_count_ones(bv->bits[idx] & 0x0000ff00); 
     246            case 1: count += frt_count_ones(bv->bits[idx] & 0x000000ff); 
     247        } 
     248    } 
     249    return bv->count = count; 
     250} 
    221251 
    222252/** 
     
    341371extern unsigned long frt_bv_hash(FrtBitVector *bv); 
    342372 
     373extern FRT_ATTR_ALWAYS_INLINE 
     374void frt_bv_capa(FrtBitVector *bv, int capa, int size) 
     375{ 
     376    int word_size = (size >> 5) + 1; 
     377    FRT_REALLOC_N(bv->bits, frt_u32, capa); 
     378    bv->capa = capa; 
     379    bv->size = size; 
     380    memset(bv->bits + word_size, (bv->extends_as_ones ? 0xFF : 0), 
     381           sizeof(frt_u32) * (capa - word_size)); 
     382} 
     383 
     384extern FRT_ATTR_ALWAYS_INLINE 
     385void frt_bv_recapa(FrtBitVector *bv, int new_capa) 
     386{ 
     387    if (bv->capa < new_capa) { 
     388        FRT_REALLOC_N(bv->bits, frt_u32, new_capa); 
     389        memset(bv->bits + bv->capa, (bv->extends_as_ones ? 0xFF : 0), 
     390               sizeof(frt_u32) * (new_capa - bv->capa)); 
     391        bv->capa = new_capa; 
     392    } 
     393} 
     394 
     395extern FRT_ATTR_ALWAYS_INLINE 
     396FrtBitVector *frt_bv_and_i(FrtBitVector *bv, FrtBitVector *bv1, 
     397                           FrtBitVector *bv2) 
     398{ 
     399    int i, size, word_size, capa = 4; 
     400 
     401    bv->extends_as_ones = (bv1->extends_as_ones & bv2->extends_as_ones); 
     402 
     403    if (bv1->extends_as_ones || bv2->extends_as_ones) 
     404         size = frt_max2(bv1->size, bv2->size); 
     405    else size = frt_min2(bv1->size, bv2->size); 
     406 
     407    word_size = (size >> 5) + 1; 
     408    capa = frt_max2(frt_round2(word_size), 4); 
     409 
     410    frt_bv_recapa(bv1, capa); 
     411    frt_bv_recapa(bv2, capa); 
     412    frt_bv_capa(bv, capa, size); 
     413 
     414    for (i = 0; i < word_size; i++) 
     415        bv->bits[i] = bv1->bits[i] & bv2->bits[i]; 
     416 
     417    frt_bv_recount(bv); 
     418    return bv; 
     419} 
     420 
     421extern FRT_ATTR_ALWAYS_INLINE 
     422FrtBitVector *frt_bv_or_i(FrtBitVector *bv, 
     423                          FrtBitVector *bv1, FrtBitVector *bv2) 
     424{ 
     425    int i; 
     426    int max_size = frt_max2(bv1->size, bv2->size); 
     427    int word_size = (max_size >> 5) + 1; 
     428    int capa = frt_max2(frt_round2(word_size), 4); 
     429 
     430    bv->extends_as_ones = (bv1->extends_as_ones | bv2->extends_as_ones); 
     431    frt_bv_recapa(bv1, capa); 
     432    frt_bv_recapa(bv2, capa); 
     433    frt_bv_capa(bv, capa, max_size); 
     434 
     435    for (i = 0; i < word_size; i++) { 
     436        bv->bits[i] = bv1->bits[i] | bv2->bits[i]; 
     437    } 
     438    frt_bv_recount(bv); 
     439    return bv; 
     440} 
     441 
     442extern FRT_ATTR_ALWAYS_INLINE 
     443FrtBitVector *frt_bv_xor_i(FrtBitVector *bv, 
     444                           FrtBitVector *bv1, FrtBitVector *bv2) 
     445{ 
     446    int i; 
     447    int max_size = frt_max2(bv1->size, bv2->size); 
     448    int word_size = (max_size >> 5) + 1; 
     449    int capa = frt_max2(frt_round2(word_size), 4); 
     450 
     451    bv->extends_as_ones = (bv1->extends_as_ones ^ bv2->extends_as_ones); 
     452    frt_bv_recapa(bv1, capa); 
     453    frt_bv_recapa(bv2, capa); 
     454    frt_bv_capa(bv, capa, max_size); 
     455 
     456    for (i = 0; i < word_size; i++) { 
     457        bv->bits[i] = bv1->bits[i] ^ bv2->bits[i]; 
     458    } 
     459    frt_bv_recount(bv); 
     460    return bv; 
     461} 
     462 
     463extern FRT_ATTR_ALWAYS_INLINE 
     464FrtBitVector *frt_bv_not_i(FrtBitVector *bv, FrtBitVector *bv1) 
     465{ 
     466    int i; 
     467    int word_size = (bv1->size >> 5) + 1; 
     468    int capa = frt_max2(frt_round2(word_size), 4); 
     469 
     470    bv->extends_as_ones = !bv1->extends_as_ones; 
     471    frt_bv_capa(bv, capa, bv1->size); 
     472 
     473    for (i = 0; i < word_size; i++) { 
     474        bv->bits[i] = ~(bv1->bits[i]); 
     475    } 
     476    frt_bv_recount(bv); 
     477    return bv; 
     478} 
     479 
    343480/** 
    344481 * ANDs two BitVectors (+bv1+ and +bv2+) together and return the resultant 
     
    349486 * @return A FrtBitVector with all bits set that are set in both bv1 and bv2 
    350487 */ 
    351 extern FrtBitVector *frt_bv_and(FrtBitVector *bv1, FrtBitVector *bv2); 
     488extern FRT_ATTR_ALWAYS_INLINE 
     489FrtBitVector *frt_bv_and(FrtBitVector *bv1, FrtBitVector *bv2) 
     490{ 
     491    return frt_bv_and_i(frt_bv_new(), bv1, bv2); 
     492} 
    352493 
    353494/** 
     
    359500 * @return A FrtBitVector with all bits set that are set in both bv1 and bv2 
    360501 */ 
    361 extern FrtBitVector *frt_bv_or(FrtBitVector *bv1, FrtBitVector *bv2); 
     502extern FRT_ATTR_ALWAYS_INLINE 
     503FrtBitVector *frt_bv_or(FrtBitVector *bv1, FrtBitVector *bv2) 
     504{ 
     505    return frt_bv_or_i(frt_bv_new(), bv1, bv2); 
     506} 
     507 
    362508 
    363509/** 
     
    369515 * @return A FrtBitVector with all bits set that are equal in bv1 and bv2 
    370516 */ 
    371 extern FrtBitVector *frt_bv_xor(FrtBitVector *bv1, FrtBitVector *bv2); 
     517extern FRT_ATTR_ALWAYS_INLINE 
     518FrtBitVector *frt_bv_xor(FrtBitVector *bv1, FrtBitVector *bv2) 
     519{ 
     520    return frt_bv_xor_i(frt_bv_new(), bv1, bv2); 
     521} 
    372522 
    373523/** 
     
    377527 * @return A FrtBitVector with all bits set that are set in both bv1 and bv2 
    378528 */ 
    379 extern FrtBitVector *frt_bv_not(FrtBitVector *bv); 
     529extern FRT_ATTR_ALWAYS_INLINE 
     530FrtBitVector *frt_bv_not(FrtBitVector *bv) 
     531{ 
     532    return frt_bv_not_i(frt_bv_new(), bv); 
     533} 
    380534 
    381535/** 
     
    387541 * @return bv1 with all bits set that where set in both bv1 and bv2 
    388542 */ 
    389 extern FrtBitVector *frt_bv_and_x(FrtBitVector *bv1, FrtBitVector *bv2); 
     543extern FRT_ATTR_ALWAYS_INLINE 
     544FrtBitVector *frt_bv_and_x(FrtBitVector *bv1, FrtBitVector *bv2) 
     545{ 
     546    return frt_bv_and_i(bv1, bv1, bv2); 
     547} 
    390548 
    391549/** 
     
    396554 * @return bv1 
    397555 */ 
    398 extern FrtBitVector *frt_bv_or_x(FrtBitVector *bv1, FrtBitVector *bv2); 
     556extern FRT_ATTR_ALWAYS_INLINE 
     557FrtBitVector *frt_bv_or_x(FrtBitVector *bv1, FrtBitVector *bv2) 
     558{ 
     559    return frt_bv_or_i(bv1, bv1, bv2); 
     560} 
    399561 
    400562/** 
     
    405567 * @return bv1 
    406568 */ 
    407 extern FrtBitVector *frt_bv_xor_x(FrtBitVector *bv1, FrtBitVector *bv2); 
     569extern FRT_ATTR_ALWAYS_INLINE 
     570FrtBitVector *frt_bv_xor_x(FrtBitVector *bv1, FrtBitVector *bv2) 
     571{ 
     572    return frt_bv_xor_i(bv1, bv1, bv2); 
     573} 
    408574 
    409575/** 
     
    413579 * @return A +bv+ with all it's bits flipped 
    414580 */ 
    415 extern FrtBitVector *frt_bv_not_x(FrtBitVector *bv); 
     581extern FRT_ATTR_ALWAYS_INLINE 
     582FrtBitVector *frt_bv_not_x(FrtBitVector *bv) 
     583{ 
     584    return frt_bv_not_i(bv, bv); 
     585} 
    416586 
    417587#ifdef __cplusplus 
  • c/src/bitvector.c

    r75ff31 rd0c804  
    3535    bv->count = 0; 
    3636    bv->size = 0; 
    37 } 
    38  
    39 int bv_recount(BitVector *bv) 
    40 { 
    41     unsigned int extra = ((bv->size & 31) >> 3) + 1; 
    42     unsigned int len   = bv->size >> 5; 
    43     unsigned int idx, count = 0; 
    44  
    45     if (bv->extends_as_ones) { 
    46         for (idx = 0; idx < len; ++idx) { 
    47             count += frt_count_zeros(bv->bits[idx]); 
    48         } 
    49         switch (extra) { 
    50             case 4: count += frt_count_zeros(bv->bits[idx] | 0x00ffffff); 
    51             case 3: count += frt_count_zeros(bv->bits[idx] | 0xff00ffff); 
    52             case 2: count += frt_count_zeros(bv->bits[idx] | 0xffff00ff); 
    53             case 1: count += frt_count_zeros(bv->bits[idx] | 0xffffff00); 
    54         } 
    55     } 
    56     else { 
    57         for (idx = 0; idx < len; ++idx) { 
    58             count += frt_count_ones(bv->bits[idx]); 
    59         } 
    60         switch (extra) { 
    61             case 4: count += frt_count_ones(bv->bits[idx] & 0xff000000); 
    62             case 3: count += frt_count_ones(bv->bits[idx] & 0x00ff0000); 
    63             case 2: count += frt_count_ones(bv->bits[idx] & 0x0000ff00); 
    64             case 1: count += frt_count_ones(bv->bits[idx] & 0x000000ff); 
    65         } 
    66     } 
    67     return bv->count = count; 
    6837} 
    6938 
     
    12998} 
    13099 
    131 static INLINE void bv_capa(BitVector *bv, int capa, int size) 
    132 { 
    133     int word_size = (size >> 5) + 1; 
    134     REALLOC_N(bv->bits, u32, capa); 
    135     bv->capa = capa; 
    136     bv->size = size; 
    137     memset(bv->bits + word_size, (bv->extends_as_ones ? 0xFF : 0), 
    138            sizeof(u32) * (capa - word_size)); 
    139 } 
    140  
    141 static INLINE void bv_recapa(BitVector *bv, int new_capa) 
    142 { 
    143     if (bv->capa < new_capa) { 
    144         REALLOC_N(bv->bits, u32, new_capa); 
    145         memset(bv->bits + bv->capa, (bv->extends_as_ones ? 0xFF : 0), 
    146                sizeof(u32) * (new_capa - bv->capa)); 
    147         bv->capa = new_capa; 
    148     } 
    149 } 
    150  
    151 static BitVector *bv_and_i(BitVector *bv, BitVector *bv1, BitVector *bv2) 
    152 { 
    153     int i; 
    154     int size; 
    155     int word_size; 
    156     int capa = 4; 
    157  
    158     bv->extends_as_ones = (bv1->extends_as_ones & bv2->extends_as_ones); 
    159  
    160     if (bv1->extends_as_ones || bv2->extends_as_ones) 
    161          size = max2(bv1->size, bv2->size); 
    162     else size = min2(bv1->size, bv2->size); 
    163  
    164     word_size = (size >> 5) + 1; 
    165     capa = max2(frt_round2(word_size), 4); 
    166  
    167     bv_recapa(bv1, capa); 
    168     bv_recapa(bv2, capa); 
    169     bv_capa(bv, capa, size); 
    170  
    171     for (i = 0; i < word_size; i++) { 
    172         bv->bits[i] = bv1->bits[i] & bv2->bits[i]; 
    173     } 
    174  
    175     bv_recount(bv); 
    176     return bv; 
    177 } 
    178  
    179 BitVector *bv_and(BitVector *bv1, BitVector *bv2) 
    180 { 
    181     return bv_and_i(bv_new(), bv1, bv2); 
    182 } 
    183  
    184 BitVector *bv_and_x(BitVector *bv1, BitVector *bv2) 
    185 { 
    186     return bv_and_i(bv1, bv1, bv2); 
    187 } 
    188  
    189 static BitVector *bv_or_i(BitVector *bv, BitVector *bv1, BitVector *bv2) 
    190 { 
    191     int i; 
    192     int max_size = max2(bv1->size, bv2->size); 
    193     int word_size = (max_size >> 5) + 1; 
    194     int capa = max2(frt_round2(word_size), 4); 
    195  
    196     bv->extends_as_ones = (bv1->extends_as_ones | bv2->extends_as_ones); 
    197     bv_recapa(bv1, capa); 
    198     bv_recapa(bv2, capa); 
    199     bv_capa(bv, capa, max_size); 
    200  
    201     for (i = 0; i < word_size; i++) { 
    202         bv->bits[i] = bv1->bits[i] | bv2->bits[i]; 
    203     } 
    204     bv_recount(bv); 
    205     return bv; 
    206 } 
    207  
    208 BitVector *bv_or(BitVector *bv1, BitVector *bv2) 
    209 { 
    210     return bv_or_i(bv_new(), bv1, bv2); 
    211 } 
    212  
    213 BitVector *bv_or_x(BitVector *bv1, BitVector *bv2) 
    214 { 
    215     return bv_or_i(bv1, bv1, bv2); 
    216 } 
    217  
    218 static BitVector *bv_xor_i(BitVector *bv, BitVector *bv1, BitVector *bv2) 
    219 { 
    220     int i; 
    221     int max_size = max2(bv1->size, bv2->size); 
    222     int word_size = (max_size >> 5) + 1; 
    223     int capa = max2(frt_round2(word_size), 4); 
    224  
    225     bv->extends_as_ones = (bv1->extends_as_ones ^ bv2->extends_as_ones); 
    226     bv_recapa(bv1, capa); 
    227     bv_recapa(bv2, capa); 
    228     bv_capa(bv, capa, max_size); 
    229  
    230     for (i = 0; i < word_size; i++) { 
    231         bv->bits[i] = bv1->bits[i] ^ bv2->bits[i]; 
    232     } 
    233     bv_recount(bv); 
    234     return bv; 
    235 } 
    236  
    237 BitVector *bv_xor(BitVector *bv1, BitVector *bv2) 
    238 { 
    239     return bv_xor_i(bv_new(), bv1, bv2); 
    240 } 
    241  
    242 BitVector *bv_xor_x(BitVector *bv1, BitVector *bv2) 
    243 { 
    244     return bv_xor_i(bv1, bv1, bv2); 
    245 } 
    246  
    247 static BitVector *bv_not_i(BitVector *bv, BitVector *bv1) 
    248 { 
    249     int i; 
    250     int word_size = (bv1->size >> 5) + 1; 
    251     int capa = max2(frt_round2(word_size), 4); 
    252  
    253     bv->extends_as_ones = !bv1->extends_as_ones; 
    254     bv_capa(bv, capa, bv1->size); 
    255  
    256     for (i = 0; i < word_size; i++) { 
    257         bv->bits[i] = ~(bv1->bits[i]); 
    258     } 
    259     bv_recount(bv); 
    260     return bv; 
    261 } 
    262  
    263 BitVector *bv_not(BitVector *bv1) 
    264 { 
    265     return bv_not_i(bv_new(), bv1); 
    266 } 
    267  
    268 BitVector *bv_not_x(BitVector *bv1) 
    269 { 
    270     return bv_not_i(bv1, bv1); 
    271 }