// returns 0 on error, 1 if ok. int and_or_test() { bitset_container_t* B1 = bitset_container_create(); bitset_container_t* B2 = bitset_container_create(); bitset_container_t* BI = bitset_container_create(); bitset_container_t* BO = bitset_container_create(); int x, c, ci, co; printf("[%s] %s\n", __FILE__, __func__); if ((B1 == NULL) || (B2 == NULL) || (BO == NULL) || (BI == NULL)) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } for (x = 0; x < (1 << 16); x += 3) { bitset_container_set(B1, (uint16_t)x); bitset_container_set(BI, (uint16_t)x); } for (x = 0; x < (1 << 16); x += 62) { // important: 62 is not divisible by 3 bitset_container_set(B2, (uint16_t)x); bitset_container_set(BI, (uint16_t)x); } for (x = 0; x < (1 << 16); x += 62 * 3) { bitset_container_set(BO, (uint16_t)x); } // we interleave O and I on purpose (to trigger bugs!) ci = bitset_container_compute_cardinality(BO); // expected intersection co = bitset_container_compute_cardinality(BI); // expected union bitset_container_and_nocard(B1, B2, BI); c = bitset_container_compute_cardinality(BI); if (c != ci) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } c = bitset_container_and(B1, B2, BI); ; if (c != ci) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } bitset_container_or_nocard(B1, B2, BO); c = bitset_container_compute_cardinality(BO); if (c != co) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } c = bitset_container_or(B1, B2, BO); if (c != co) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } bitset_container_free(B1); bitset_container_free(B2); bitset_container_free(BI); bitset_container_free(BO); return 1; }
// returns 0 on error, 1 if ok. int printf_test() { printf("[%s] %s\n", __FILE__, __func__); bitset_container_t* B = bitset_container_create(); bitset_container_set(B, (uint16_t)1); bitset_container_set(B, (uint16_t)2); bitset_container_set(B, (uint16_t)3); bitset_container_set(B, (uint16_t)10); bitset_container_set(B, (uint16_t)10000); bitset_container_printf(B); // does it crash? printf("\n"); bitset_container_free(B); return 1; }
int set_test(bitset_container_t* B) { int x; for (x = 0; x < 1 << 16; x += 3) { bitset_container_set(B, (uint16_t)x); } return 0; }
// returns 0 on error, 1 if ok. int to_uint32_array_test() { printf("[%s] %s\n", __FILE__, __func__); for (int offset = 1; offset < 128; offset *= 2) { bitset_container_t* B = bitset_container_create(); for (int k = 0; k < (1 << 16); k += offset) { bitset_container_set(B, (uint16_t)k); } int card = bitset_container_cardinality(B); uint32_t* out = malloc(sizeof(uint32_t) * (card + sizeof(__m256i))); int nc = bitset_container_to_uint32_array(out, B, 0); if (card != nc) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } for (int k = 1; k < nc; ++k) { if (out[k] != offset + out[k - 1]) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } } free(out); bitset_container_free(B); } return 1; }
// returns 0 on error, 1 if ok. int set_get_test() { bitset_container_t* B = bitset_container_create(); int x; printf("[%s] %s\n", __FILE__, __func__); if (B == NULL) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } for (x = 0; x < 1 << 16; x++) { assert(!bitset_container_get(B, x)); } for (x = 0; x < 1 << 16; x += 3) { assert(bitset_container_cardinality(B) == x / 3); assert(!bitset_container_get(B, x)); bitset_container_set(B, (uint16_t)x); assert(bitset_container_get(B, x)); assert(bitset_container_cardinality(B) == x / 3 + 1); } for (x = 0; x < 1 << 16; x++) { int isset = bitset_container_get(B, (uint16_t)x); int shouldbeset = (x / 3 * 3 == x); if (isset != shouldbeset) { printf("Bug %s, line %d \n", __FILE__, __LINE__); bitset_container_free(B); return 0; } } if (bitset_container_cardinality(B) != (1 << 16) / 3 + 1) { printf("Bug %s, line %d \n", __FILE__, __LINE__); bitset_container_free(B); return 0; } if (bitset_container_compute_cardinality(B) != (1 << 16) / 3 + 1) { printf("Bug %s, line %d \n", __FILE__, __LINE__); bitset_container_free(B); return 0; } for (x = 0; x < 1 << 16; x += 3) { bitset_container_unset(B, (uint16_t)x); } if (bitset_container_cardinality(B) != 0) { printf("Bug %s, line %d \n", __FILE__, __LINE__); bitset_container_free(B); return 0; } if (bitset_container_compute_cardinality(B) != 0) { printf("Bug %s, line %d \n", __FILE__, __LINE__); bitset_container_free(B); return 0; } bitset_container_free(B); return 1; }
// returns 0 on error, 1 if ok. int xor_test() { bitset_container_t* B1 = bitset_container_create(); bitset_container_t* B2 = bitset_container_create(); bitset_container_t* BI = bitset_container_create(); int x, c, cx; printf("[%s] %s\n", __FILE__, __func__); for (x = 0; x < (1 << 16); x += 3) { bitset_container_set(B1, (uint16_t)x); bitset_container_set(BI, (uint16_t)x); } for (x = 0; x < (1 << 16); x += 62) { // important: 62 is not divisible by 3 bitset_container_set(B2, (uint16_t)x); bitset_container_set(BI, (uint16_t)x); } for (x = 0; x < (1 << 16); x += 62 * 3) { bitset_container_unset(BI, (uint16_t)x); } cx = bitset_container_compute_cardinality(BI); // expected xor bitset_container_xor_nocard(B1, B2, BI); c = bitset_container_compute_cardinality(BI); if (c != cx) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } c = bitset_container_xor(B1, B2, BI); if (c != cx) { printf("Bug %s, line %d \n", __FILE__, __LINE__); return 0; } bitset_container_free(B1); bitset_container_free(B2); bitset_container_free(BI); return 1; }
int main() { int repeat = 500; int size = (1 << 16) / 3; tellmeall(); printf("bitset container benchmarks\n"); bitset_container_t* B = bitset_container_create(); BEST_TIME(set_test(B), 0, repeat, size); int answer = get_test(B); size = 1 << 16; BEST_TIME(get_test(B), answer, repeat, size); BEST_TIME(bitset_container_cardinality(B), answer, repeat, 1); BEST_TIME(bitset_container_compute_cardinality(B), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); size = (1 << 16) / 3; BEST_TIME(unset_test(B), 0, repeat, size); bitset_container_free(B); for (int howmany = 4096; howmany <= (1 << 16); howmany *= 2) { bitset_container_t* Bt = bitset_container_create(); while (bitset_container_cardinality(Bt) < howmany) { bitset_container_set(Bt, (uint16_t)pcg32_random()); } size_t nbrtestvalues = 1024; uint16_t* testvalues = malloc(nbrtestvalues * sizeof(uint16_t)); printf("\n number of values in container = %d\n", bitset_container_cardinality(Bt)); int card = bitset_container_cardinality(Bt); uint32_t* out = malloc(sizeof(uint32_t) * (unsigned)card + 32); BEST_TIME(bitset_container_to_uint32_array(out, Bt, 1234), card, repeat, card); free(out); BEST_TIME_PRE_ARRAY(Bt, bitset_container_get, bitset_cache_prefetch, testvalues, nbrtestvalues); BEST_TIME_PRE_ARRAY(Bt, bitset_container_get, bitset_cache_flush, testvalues, nbrtestvalues); free(testvalues); bitset_container_free(Bt); } printf("\n"); bitset_container_t* B1 = bitset_container_create(); for (int x = 0; x < 1 << 16; x += 3) { bitset_container_set(B1, (uint16_t)x); } bitset_container_t* B2 = bitset_container_create(); for (int x = 0; x < 1 << 16; x += 5) { bitset_container_set(B2, (uint16_t)x); } bitset_container_t* BO = bitset_container_create(); BEST_TIME(bitset_container_or_nocard(B1, B2, BO), -1, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); answer = bitset_container_compute_cardinality(BO); BEST_TIME(bitset_container_or(B1, B2, BO), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); BEST_TIME(bitset_container_cardinality(BO), answer, repeat, 1); BEST_TIME(bitset_container_compute_cardinality(BO), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); BEST_TIME(bitset_container_and_nocard(B1, B2, BO), -1, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); answer = bitset_container_compute_cardinality(BO); BEST_TIME(bitset_container_and(B1, B2, BO), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); BEST_TIME(bitset_container_cardinality(BO), answer, repeat, 1); BEST_TIME(bitset_container_compute_cardinality(BO), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); // next we are going to benchmark conversion from bitset to array (an // important step) bitset_container_clear(B1); for (int k = 0; k < 4096; ++k) { bitset_container_set(B1, (uint16_t)ranged_random(1 << 16)); } answer = get_cardinality_through_conversion_to_array(B1); BEST_TIME(get_cardinality_through_conversion_to_array(B1), answer, repeat, BITSET_CONTAINER_SIZE_IN_WORDS); bitset_container_free(BO); bitset_container_free(B1); bitset_container_free(B2); return 0; }