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
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();
|
|
}
|