Skip to content

Instantly share code, notes, and snippets.

@seantalts
Last active August 3, 2018 00:20
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 seantalts/61eaf261fcdd2e3e0720c9c3636293c2 to your computer and use it in GitHub Desktop.
Save seantalts/61eaf261fcdd2e3e0720c9c3636293c2 to your computer and use it in GitHub Desktop.
silly micro benchmarks for std::function vs custom functors
#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