Skip to content

Instantly share code, notes, and snippets.

@williame
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save williame/482fee74d096e47e006b to your computer and use it in GitHub Desktop.
Save williame/482fee74d096e47e006b to your computer and use it in GitHub Desktop.
benchmark iterating over set bits in a uint32_t
#include <cinttypes>
#include <cstdlib>
#include <ctime>
#include <iostream>
int main(int argc, char** args) {
srand(time(NULL));
const int NUM_LOOPS = rand() & 0xffff;
std::cout << "testing with " << NUM_LOOPS << " loops" << std::endl;
// make some test data
uint32_t test_data[1000];
for(auto &mask: test_data)
mask = rand();
// test simple loop
auto start_time = clock();
uint32_t check = 0;
for(auto loop=NUM_LOOPS; loop-- > 0; ) {
for(auto mask: test_data) {
for(auto i=0; i<32; i++) {
if(mask & (1U << i)) {
// payload
check += i;
}
}
}
}
std::cout << check << " loop (simple) took " << ((float)(clock() - start_time) / CLOCKS_PER_SEC) << "s" << std::endl;
// test early-out loop
start_time = clock();
check = 0;
for(auto loop=NUM_LOOPS; loop-- > 0; ) {
for(auto mask: test_data) {
for(uint32_t i=0, m=mask; m; i++, m>>=1) {
if(m & 1) {
// payload
check += i;
}
}
}
}
std::cout << check << " loop (early out) took " << ((float)(clock() - start_time) / CLOCKS_PER_SEC) << "s" << std::endl;
// test ffs
start_time = clock();
check = 0;
for(auto loop=NUM_LOOPS; loop-- > 0; ) {
for(auto mask: test_data) {
for(uint32_t m = mask, i = ~0U; m; ) {
auto shift = __builtin_ffs(m);
m >>= shift;
i += shift;
// payload
check += i;
}
}
}
std::cout << check << " ffs took " << ((float)(clock() - start_time) / CLOCKS_PER_SEC) << "s" << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment