Last active
August 3, 2018 00:20
-
-
Save seantalts/61eaf261fcdd2e3e0720c9c3636293c2 to your computer and use it in GitHub Desktop.
silly micro benchmarks for std::function vs custom functors
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 <vector> | |
#include <functional> | |
#include <Eigen/Dense> | |
#include <algorithm> | |
#include <iostream> | |
// CONFIGURABLE SIZES | |
typedef unsigned int index_t; // determines max expression size | |
typedef double real_t; // basic scalar type | |
typedef std::vector<real_t> vec_t; // vector of scalars | |
// SIMPLE MEMORY ARENA | |
std::size_t MEM_SIZE = 1024 * 1024 * 1024; // 1 GB | |
char* ARENA = static_cast<char*>(malloc(MEM_SIZE)); // ** global ** | |
char* ARENA_NEXT = ARENA; // ** global ** | |
inline void clear_arena() { ARENA_NEXT = ARENA; } | |
inline char* arena_malloc(std::size_t nbytes) { | |
char* bytes = ARENA_NEXT; | |
ARENA_NEXT += nbytes; | |
return bytes; | |
} | |
template <typename T> | |
inline T* arena_array_malloc(std::size_t n) { | |
return static_cast<T*>(arena_malloc(sizeof(T) * n)); | |
} | |
// STACK OF CHAINABLES FOR REVERSE PASS IN ARENA | |
struct chainable { | |
virtual void operator()(vec_t& adj) const {} | |
static inline void* operator new(std::size_t nbytes) { | |
std::cout << "arena allocating nbytes = " << nbytes << std::endl; | |
return arena_malloc(nbytes); | |
} | |
}; | |
struct mat_mul : chainable { | |
Eigen::MatrixXd mat1_; | |
Eigen::MatrixXd mat2_; | |
mat_mul(Eigen::MatrixXd mat1, Eigen::MatrixXd mat2) | |
: mat1_(mat1), mat2_(mat2) {} | |
void operator()(vec_t& adj) const { | |
Eigen::MatrixXd mat3 = mat1_ * mat2_; | |
size_t i = 0; | |
for (size_t i = 0; i < adj.size(); i++) { | |
adj[i] += mat3(i); | |
} | |
} | |
}; | |
std::vector<chainable> chainables; | |
std::vector<std::function<void(vec_t&)>> stdfuns; | |
void test_chainable() { | |
for (size_t dim : {1024 }){ //, 2048, 4096}) { | |
for (int i = 0; i < 10; i++) { | |
Eigen::MatrixXd mat1 = Eigen::MatrixXd::Random(dim, dim); | |
Eigen::MatrixXd mat2 = Eigen::MatrixXd::Random(dim, dim); | |
chainables.push_back(mat_mul(mat1, mat2)); | |
} | |
} | |
vec_t g(1024); | |
for (int i = 0; i < g.size(); ++i) { | |
g[i] = i; | |
} | |
for (auto&& f : chainables) { | |
f(g); | |
} | |
std::cout << g[24] << std::endl; | |
}; | |
void test_stdfuns() { | |
for (size_t dim : {1024 }){ //, 2048, 4096}) { | |
for (int i = 0; i < 10; i++) { | |
Eigen::MatrixXd mat1 = Eigen::MatrixXd::Random(dim, dim); | |
Eigen::MatrixXd mat2 = Eigen::MatrixXd::Random(dim, dim); | |
stdfuns.push_back([=](vec_t& adj){ | |
Eigen::MatrixXd mat3 = mat1 * mat2; | |
size_t i = 0; | |
for (size_t i = 0; i < adj.size(); i++) { | |
adj[i] += mat3(i); | |
} | |
}); | |
} | |
} | |
vec_t g(1024); | |
for (int i = 0; i < g.size(); ++i) { | |
g[i] = i; | |
} | |
for (auto&& f : stdfuns) { | |
f(g); | |
} | |
std::cout << g[24] << std::endl; | |
}; | |
#include <ctime> | |
int main() { | |
std::clock_t start2 = std::clock(); | |
test_stdfuns(); | |
test_stdfuns(); | |
test_stdfuns(); | |
std::cout << "Time: " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl; | |
std::clock_t start = std::clock(); | |
test_chainable(); | |
test_chainable(); | |
test_chainable(); | |
std::cout << "Time: " << (std::clock() - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment