Skip to content

Instantly share code, notes, and snippets.

@Lautitia
Forked from wuye9036/gist:6657313
Created September 22, 2013 07:39
Show Gist options
  • Save Lautitia/6657668 to your computer and use it in GitHub Desktop.
Save Lautitia/6657668 to your computer and use it in GitHub Desktop.
// TestApp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <utility>
#include <chrono>
#include <vector>
#include <algorithm>
#include <iostream>
#include <future>
#include <atomic>
#include <thread>
using namespace std;
static const int ARRAY_SIZE = 2048 * 2048 * 4;
struct calc
{
calc()
{
base = new float[ARRAY_SIZE];
}
virtual ~calc()
{
delete [] base;
}
void init()
{
for(int i = 0; i < ARRAY_SIZE; ++i)
{
base[i] = static_cast<float>(i);
}
}
inline void do_with_fnptr(int i)
{
fn(base, i);
}
inline void do_with_mfnptr(int i)
{
(this->*mfn)(i);
}
inline void do_with_fnobj(int i)
{
fnobj(i);
}
virtual void do_with_vfn(int i) = 0;
public:
float* base;
void (*fn)(float* base, int i);
void (calc::*mfn)(int i);
std::function<void (int)> fnobj;
static void add2(float* base, int i)
{
base[i] += 2;
}
static void mul2(float* base, int i)
{
base[i] *= 2;
}
static void do_nothing(float* /*base*/, int /*i*/)
{
}
void madd2(int i)
{
*(base+i) += 2;
}
void mmul2(int i)
{
*(base+i) *= 2;
}
};
struct calc_add2: public calc
{
calc_add2()
{
fn = &calc::add2;
mfn = &calc::madd2;
fnobj = [this](int i) { this->base[i] += 2; };
}
void do_with_vfn(int i)
{
base[i] += 2;
}
};
struct calc_mul2: public calc
{
calc_mul2()
{
fn = &calc::mul2;
mfn = &calc::mmul2;
fnobj = [this](int i) { this->base[i] *= 2; };
}
void do_with_vfn(int i)
{
base[i] *= 2;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
chrono::duration<chrono::high_resolution_clock::rep, chrono::high_resolution_clock::period> duration;
calc* obj = nullptr;
if(argc == 1)
{
obj = new calc_add2();
}
else
{
obj = new calc_mul2();
}
{
obj->init();
auto startTime = chrono::high_resolution_clock::now();
for(size_t j = 0; j < 20; ++j)
{
if(argc == 1)
{
for(int i = 0; i < ARRAY_SIZE; ++i)
{
obj->base[i] += 2;
}
}
else
{
for(int i = 0; i < ARRAY_SIZE; ++i)
{
obj->base[i] *= 2;
}
}
}
auto endTime = chrono::high_resolution_clock::now();
duration = (endTime - startTime);
auto elapsedMS = chrono::duration_cast<chrono::milliseconds>(duration).count();
cout << "Branch per batch Elapsed: " << elapsedMS << "ms" << endl;
}
{
obj->init();
auto startTime = chrono::high_resolution_clock::now();
for(size_t j = 0; j < 20; ++j)
{
for(int i = 0; i < ARRAY_SIZE; ++i)
{
if(argc == 1)
{
obj->base[i] += 2;
}
else
{
obj->base[i] *= 2;
}
}
}
auto endTime = chrono::high_resolution_clock::now();
duration = (endTime - startTime);
auto elapsedMS = chrono::duration_cast<chrono::milliseconds>(duration).count();
cout << "Branch per scalar Elapsed: " << elapsedMS << "ms" << endl;
}
{
obj->init();
auto startTime = chrono::high_resolution_clock::now();
for(size_t j = 0; j < 20; ++j)
{
for(int i = 0; i < ARRAY_SIZE; ++i)
{
obj->do_with_fnptr(i);
}
}
auto endTime = chrono::high_resolution_clock::now();
duration = (endTime - startTime);
auto elapsedMS = chrono::duration_cast<chrono::milliseconds>(duration).count();
cout << "Fn Ptr Elapsed: " << elapsedMS << "ms" << endl;
}
{
obj->init();
auto startTime = chrono::high_resolution_clock::now();
for(size_t j = 0; j < 20; ++j)
{
for(int i = 0; i < ARRAY_SIZE; ++i)
{
obj->do_with_vfn(i);
}
}
auto endTime = chrono::high_resolution_clock::now();
duration = (endTime - startTime);
auto elapsedMS = chrono::duration_cast<chrono::milliseconds>(duration).count();
cout << "Virtual Func Elapsed: " << elapsedMS << "ms" << endl;
}
{
obj->init();
auto startTime = chrono::high_resolution_clock::now();
for(size_t j = 0; j < 20; ++j)
{
for(int i = 0; i < ARRAY_SIZE; ++i)
{
obj->do_with_mfnptr(i);
}
}
auto endTime = chrono::high_resolution_clock::now();
duration = (endTime - startTime);
auto elapsedMS = chrono::duration_cast<chrono::milliseconds>(duration).count();
cout << "Member Func Ptr Elapsed: " << elapsedMS << "ms" << endl;
}
{
obj->init();
auto startTime = chrono::high_resolution_clock::now();
for(size_t j = 0; j < 20; ++j)
{
for(int i = 0; i < ARRAY_SIZE; ++i)
{
obj->do_with_fnobj(i);
}
}
auto endTime = chrono::high_resolution_clock::now();
duration = (endTime - startTime);
auto elapsedMS = chrono::duration_cast<chrono::milliseconds>(duration).count();
cout << "Function Object with Lambda Elapsed: " << elapsedMS << "ms" << endl;
}
delete obj;
system( "pause" );
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment