Last active
June 12, 2016 20:53
-
-
Save astoeckel/3800da9ccbffe7369d3025b3b0c7dc7d to your computer and use it in GitHub Desktop.
Using an array of bitfields in the bencharking code by Tony D in http://stackoverflow.com/questions/4240974/when-is-it-worthwhile-to-use-bit-fields
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <time.h> | |
#include <stdlib.h> | |
#include <iostream> | |
#include <vector> | |
struct A | |
{ | |
void a(unsigned n) { a_ = n; } | |
void b(unsigned n) { b_ = n; } | |
void c(unsigned n) { c_ = n; } | |
void d(unsigned n) { d_ = n; } | |
unsigned a() { return a_; } | |
unsigned b() { return b_; } | |
unsigned c() { return c_; } | |
unsigned d() { return d_; } | |
volatile unsigned a_:1, | |
b_:5, | |
c_:2, | |
d_:8; | |
}; | |
struct B | |
{ | |
void a(unsigned n) { a_ = n; } | |
void b(unsigned n) { b_ = n; } | |
void c(unsigned n) { c_ = n; } | |
void d(unsigned n) { d_ = n; } | |
unsigned a() { return a_; } | |
unsigned b() { return b_; } | |
unsigned c() { return c_; } | |
unsigned d() { return d_; } | |
volatile unsigned a_, b_, c_, d_; | |
}; | |
struct C | |
{ | |
void a(unsigned n) { x_ &= ~0x01; x_ |= n; } | |
void b(unsigned n) { x_ &= ~0x3E; x_ |= n << 1; } | |
void c(unsigned n) { x_ &= ~0xC0; x_ |= n << 6; } | |
void d(unsigned n) { x_ &= ~0xFF00; x_ |= n << 8; } | |
unsigned a() const { return x_ & 0x01; } | |
unsigned b() const { return (x_ & 0x3E) >> 1; } | |
unsigned c() const { return (x_ & 0xC0) >> 6; } | |
unsigned d() const { return (x_ & 0xFF00) >> 8; } | |
volatile unsigned x_; | |
}; | |
struct Timer | |
{ | |
Timer() { get(&start_tp); } | |
double elapsed() const { | |
struct timespec end_tp; | |
get(&end_tp); | |
return (end_tp.tv_sec - start_tp.tv_sec) + | |
(1E-9 * end_tp.tv_nsec - 1E-9 * start_tp.tv_nsec); | |
} | |
private: | |
static void get(struct timespec* p_tp) { | |
if (clock_gettime(CLOCK_REALTIME, p_tp) != 0) | |
{ | |
std::cerr << "clock_gettime() error\n"; | |
exit(EXIT_FAILURE); | |
} | |
} | |
struct timespec start_tp; | |
}; | |
template <typename T> | |
unsigned f() | |
{ | |
int n = 0; | |
Timer timer; | |
std::vector<T> ts(1024 * 1024 * 16); | |
for (size_t i = 0, idx = 0; i < 10000000; ++i) | |
{ | |
T& t = ts[idx]; | |
t.a(i & 0x01); | |
t.b(i & 0x1F); | |
t.c(i & 0x03); | |
t.d(i & 0xFF); | |
n += t.a() + t.b() + t.c() + t.d(); | |
idx++; | |
if (idx >= ts.size()) { | |
idx = 0; | |
} | |
} | |
std::cout << timer.elapsed() << '\n'; | |
return n; | |
} | |
int main() | |
{ | |
std::cout << "bitfields: " << f<A>() << '\n'; | |
std::cout << "separate ints: " << f<B>() << '\n'; | |
std::cout << "explicit and/or/shift: " << f<C>() << '\n'; | |
} |
Author
astoeckel
commented
Jun 12, 2016
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment