-
-
Save Lautitia/6657668 to your computer and use it in GitHub Desktop.
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
// 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