You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

284 lines
8.2 KiB

#include <memory>
#include <cassert>
#include <cstdio>
#include <stdlib.h>
#include <algorithm>
#include <vector>
// enable debugging code in spp_bitset.h
#define SPP_TEST 1
#include <sparsepp/spp_timer.h>
#include <sparsepp/spp_memory.h>
#include <sparsepp/spp_bitset.h>
using namespace std;
// -----------------------------------------------------------
// -----------------------------------------------------------
template <size_t N>
class TestBitset
{
public:
typedef spp::spp_bitset<N> BS;
TestBitset()
{}
void test_set(size_t num_iter)
{
size_t num_errors = 0;
BS bs, bs2;
printf("testing set on spp_bitset<%zu> , num_iter=%6zu -> ", N, num_iter);
for (size_t i=0; i<num_iter; ++i)
{
bs.reset();
bs2.reset();
size_t start = rand() % N;
size_t to = start + rand() % (N - start);
bs.set(start, to);
bs2.set_naive(start, to);
bool same = bs == bs2;
if (!same)
++num_errors;
assert(same);
}
printf("num_errors = %zu\n", num_errors);
}
void test_reset(size_t num_iter)
{
size_t num_errors = 0;
BS bs, bs2;
printf("testing reset on spp_bitset<%zu>, num_iter=%6zu -> ", N, num_iter);
for (size_t i=0; i<num_iter; ++i)
{
bs.set();
bs2.set();
size_t start = rand() % N;
size_t to = start + rand() % (N - start);
bs.reset(start, to);
bs2.reset_naive(start, to);
bool same = bs == bs2;
if (!same)
++num_errors;
assert(same);
}
printf("num_errors = %zu\n", num_errors);
}
void test_all(size_t num_iter)
{
size_t num_errors = 0;
BS bs;
printf("testing all() on spp_bitset<%zu>, num_iter=%6zu -> ", N, num_iter);
for (size_t i=0; i<4 * N; ++i)
{
bs.set(rand() % N);
if (i > 2 * N)
{
for (size_t j=0; j<num_iter; ++j)
{
size_t start = rand() % N;
size_t to = start + rand() % (N - start);
bool same = bs.all(start, to) == bs.all_naive(start, to);
if (!same)
++num_errors;
assert(same);
}
size_t start = 0, start_naive = 1;
bs.all(start);
bs.all_naive(start_naive);
bool same = (start == start_naive);
if (!same)
++num_errors;
assert(same);
}
}
printf("num_errors = %zu\n", num_errors);
}
void test_any(size_t num_iter)
{
size_t num_errors = 0;
BS bs;
printf("testing any() on spp_bitset<%zu>, num_iter=%6zu -> ", N, num_iter);
for (size_t i=0; i<num_iter; ++i)
{
bs.set(rand() % N);
for (size_t j=0; j<100; ++j)
{
size_t start = rand() % N;
size_t to = start + rand() % (N - start);
bool same = bs.any(start, to) == bs.any_naive(start, to);
if (!same)
++num_errors;
assert(same);
}
}
printf("num_errors = %zu\n", num_errors);
}
void test_longest(size_t num_iter)
{
size_t num_errors = 0;
BS bs, bs2;
assert(bs.longest_zero_sequence() == N);
bs.set(0);
assert(bs.longest_zero_sequence() == N-1);
bs.set(10);
assert(bs.find_next_n(3, 8) == 11);
assert(bs.find_next_n(3, 6) == 6);
assert(bs.find_next_n(3, N-2) == 1);
assert(bs.longest_zero_sequence() == N-11);
if (N > 1000)
{
bs.set(1000);
size_t longest = bs.longest_zero_sequence();
assert(longest == 1000-11 || longest == N-1001);
if (!(longest == 1000-11 || longest == N-1001))
++num_errors;
}
spp::Timer<std::milli> timer_lz;
spp::Timer<std::milli> timer_lz_slow;
float lz_time(0), lz_time_slow(0);
printf("testing longest_zero_sequence() , num_iter=%6zu -> ", num_iter);
srand(1);
for (size_t i=0; i<num_iter; ++i)
{
bs.reset();
for (size_t j=0; j<N; ++j)
{
bs.set(rand() % N);
timer_lz.snap();
size_t lz1 = bs.longest_zero_sequence();
lz_time += timer_lz.get_delta();
timer_lz_slow.snap();
size_t lz2 = bs.longest_zero_sequence_naive();
lz_time_slow += timer_lz_slow.get_delta();
num_errors += (lz1 != lz2);
assert(!num_errors);
}
}
printf("num_errors = %zu, time=%7.1f, slow_time=%7.1f\n", num_errors, lz_time, lz_time_slow);
}
void test_longest2(size_t num_iter)
{
size_t num_errors = 0;
BS bs, bs2;
assert(bs.longest_zero_sequence() == N);
bs.set(0);
assert(bs.longest_zero_sequence() == N-1);
bs.set(10);
assert(bs.find_next_n(3, 8) == 11);
assert(bs.find_next_n(3, 6) == 6);
assert(bs.find_next_n(3, N-2) == 1);
assert(bs.longest_zero_sequence() == N-11);
if (N > 1000)
{
bs.set(1000);
size_t longest = bs.longest_zero_sequence();
assert(longest == 1000-11 || longest == N-1001);
if (!(longest == 1000-11 || longest == N-1001))
++num_errors;
}
spp::Timer<std::milli> timer_lz;
spp::Timer<std::milli> timer_lz_slow;
float lz_time(0), lz_time_slow(0);
printf("testing longest_zero_sequence2() , num_iter=%6zu -> ", num_iter);
srand(1);
for (size_t i=0; i<num_iter; ++i)
{
bs.reset();
for (size_t j=0; j<N; ++j)
{
bs.set(rand() % N);
size_t start_pos1 = 0, start_pos2 = 0;
timer_lz.snap();
size_t lz1 = bs.longest_zero_sequence(64, start_pos1);
lz_time += timer_lz.get_delta();
timer_lz_slow.snap();
size_t lz2 = bs.longest_zero_sequence_naive(64, start_pos2);
lz_time_slow += timer_lz_slow.get_delta();
assert(start_pos1 == start_pos2);
num_errors += (lz1 != lz2) || (start_pos1 != start_pos2);
assert(!num_errors);
}
}
printf("num_errors = %zu, time=%7.1f, slow_time=%7.1f\n", num_errors, lz_time, lz_time_slow);
}
void test_ctz(size_t num_iter)
{
size_t num_errors = 0;
spp::Timer<std::milli> timer_ctz;
spp::Timer<std::milli> timer_ctz_slow;
float ctz_time(0), ctz_time_slow(0);
printf("testing count_trailing_zeroes() , num_iter=%6zu -> ", num_iter);
for (size_t i=0; i<num_iter; ++i)
{
size_t v = rand() ^ (rand() << 16);
timer_ctz.snap();
uint32_t ctz1 = spp::count_trailing_zeroes(v);
ctz_time += timer_ctz.get_delta();
timer_ctz_slow.snap();
size_t ctz2 = spp::count_trailing_zeroes_naive(v);
ctz_time_slow += timer_ctz_slow.get_delta();
num_errors += (ctz1 != ctz2);
assert(!num_errors);
}
printf("num_errors = %zu, time=%7.1f, slow_time=%7.1f\n", num_errors, ctz_time, ctz_time_slow);
}
void run()
{
test_ctz(10000);
test_all(10000);
test_any(1000);
test_set(1000);
test_reset(1000);
test_longest(200);
test_longest2(200);
}
};
// -----------------------------------------------------------
// -----------------------------------------------------------
int main()
{
TestBitset<1024> test_bitset_1024;
test_bitset_1024.run();
TestBitset<4096> test_bitset_4096;
test_bitset_4096.run();
//TestBitset<8192> test_bitset_8192;
//test_bitset_8192.run();
}