Skip to content

Instantly share code, notes, and snippets.

@CryptoManiac
Created November 8, 2016 00:20
Show Gist options
  • Save CryptoManiac/1fc20439c00cf2b5848e736d824fb5e5 to your computer and use it in GitHub Desktop.
Save CryptoManiac/1fc20439c00cf2b5848e736d824fb5e5 to your computer and use it in GitHub Desktop.
#include <sys/timeb.h>
#include <sys/types.h>
#include <vector>
#ifdef _WIN32
# include <windows.h>
#else
# include <sys/time.h>
# include <unistd.h>
#endif
#include <iostream>
#include <iomanip>
#include <cstdint>
#if !defined(__clang__) && !defined(__INTEL_COMPILER)
#define __volatile__ volatile
#else
#define __volatile__
#endif
using namespace std;
double time_s()
{
#if defined(_WIN32)
struct __timeb64 time_struct;
int64_t time_ms;
_ftime64_s(&time_struct);
time_ms = (int64_t)time_struct.time;
time_ms *= 1000;
time_ms += time_struct.millitm;
return (time_ms / 1000.0);
#else
struct timeval time_struct;
int64_t time_ms;
gettimeofday(&time_struct, 0);
time_ms = (int64_t)time_struct.tv_sec;
time_ms *= 1000;
time_ms += (time_struct.tv_usec / 1000);
return (time_ms / 1000.0);
#endif
}
#define HALT 0
#define PUSH 1
#define DEC 2
#define JUMP_NZ 3
#ifdef _MSC_VER
# ifndef __INTEL_COMPILER_BUILD_DATE
# ifdef _WIN64
# error "MSVC64 isn't supported, please use clang or intel c++ compiler"
# else
# define STORE(index,label) __asm lea eax, label __asm mov edx, data\
__asm mov [edx][index * TYPE program],eax
# define JUMP() { void* addr = *(ip++); __asm jmp addr }
# define JUMP_INDIRECT() { void* addr = program[*(code++)]; __asm jmp addr }
# endif
# else
# define STORE(index,label) program[index] = &&label
# define JUMP() goto **(ip++)
# define JUMP_INDIRECT() goto *program[*(code++)]
# endif
#else
# define STORE(index,label) program[index] = &&label
# define JUMP() goto **(ip++)
# define JUMP_INDIRECT() goto *program[*(code++)]
#endif
#define GET_OPCODES 0
#define RUN 1
void execute_direct(void** program, vector<size_t>& stack, int operation) {
void** ip = (void**)program;
if (operation == GET_OPCODES) goto get_opcodes;
JUMP();
op_halt:
return;
op_push:
stack.push_back(*((size_t*)(ip++)));
JUMP();
op_dec:
{
stack[stack.size() - 1]--;
JUMP();
}
op_jump_nz:
{
auto v = stack[stack.size() - 1];
auto target = *(ip++);
if (v) {
ip = (void**)target;
}
JUMP();
}
get_opcodes:
STORE(HALT, op_halt);
STORE(PUSH, op_push);
STORE(DEC, op_dec);
STORE(JUMP_NZ, op_jump_nz);
}
void execute_indirect(size_t* code, vector<size_t>& stack, int operation) {
void* buf[4];
void** program = &buf[0];
STORE(HALT, op_halt);
STORE(PUSH, op_push);
STORE(DEC, op_dec);
STORE(JUMP_NZ, op_jump_nz);
JUMP_INDIRECT();
op_halt:
return;
op_push:
stack.push_back(*((size_t*)(code++)));
JUMP_INDIRECT();
op_dec:
{
stack[stack.size() - 1]--;
JUMP_INDIRECT();
}
op_jump_nz:
{
auto target = *(code++);
auto v = stack[stack.size() - 1];
if (v) {
code = (size_t*)target;
}
JUMP_INDIRECT();
}
get_opcodes:
STORE(HALT, op_halt);
STORE(PUSH, op_push);
STORE(DEC, op_dec);
STORE(JUMP_NZ, op_jump_nz);
}
void test_direct() {
vector<size_t> stack;
void* opcodes[4];
void* program[6];
double start_time, end_time;
execute_direct(opcodes, stack, GET_OPCODES);
program[0] = opcodes[PUSH];
program[1] = (void*)2000000000;
program[2] = opcodes[DEC];
program[3] = opcodes[JUMP_NZ];
program[4] = &program[2];
program[5] = opcodes[HALT];
start_time = time_s();
execute_direct(program, stack, RUN);
end_time = time_s();
cout << "Direct threaded done in " << (end_time - start_time) << " seconds." << endl;
}
void test_indirect() {
vector<size_t> stack;
size_t program[6];
double start_time, end_time;
program[0] = PUSH;
program[1] = 2000000000;
program[2] = DEC;
program[3] = JUMP_NZ;
program[4] = (size_t)&program[2];
program[5] = HALT;
start_time = time_s();
execute_indirect(program, stack, RUN);
end_time = time_s();
cout << "Indirect threaded done in " << (end_time - start_time) << " seconds." << endl;
}
int main() {
test_direct();
test_indirect();
return 0;
}
@svost
Copy link

svost commented Nov 8, 2016

model name : Intel(R) Xeon(R) CPU 5130 @ 2.00GHz
$ g++-5 -std=c++11 -O2 dispatchtest_stack.cxx
$ ./a.out && ./a.out && ./a.out
Direct threaded done in 10.892 seconds.
Indirect threaded done in 12.792 seconds.
Direct threaded done in 10.895 seconds.
Indirect threaded done in 12.795 seconds.
Direct threaded done in 10.892 seconds.
Indirect threaded done in 12.791 seconds.
$ g++-6 -std=c++11 -O2 dispatchtest_stack.cxx
$ ./a.out && ./a.out && ./a.out
Direct threaded done in 10.894 seconds.
Indirect threaded done in 12.794 seconds.
Direct threaded done in 10.896 seconds.
Indirect threaded done in 12.79 seconds.
Direct threaded done in 10.894 seconds.
Indirect threaded done in 12.793 seconds.
$ clang++ -std=c++11 -O2 dispatchtest_stack.cxx
$ ./a.out && ./a.out && ./a.out
Direct threaded done in 7.514 seconds.
Indirect threaded done in 11.912 seconds.
Direct threaded done in 7.511 seconds.
Indirect threaded done in 11.9 seconds.
Direct threaded done in 7.511 seconds.
Indirect threaded done in 11.859 seconds.
$ icpc -std=c++11 -O2 dispatchtest_stack.cxx
$ ./a.out && ./a.out && ./a.out
Direct threaded done in 10.392 seconds.
Indirect threaded done in 12.434 seconds.
Direct threaded done in 10.452 seconds.
Indirect threaded done in 12.454 seconds.
Direct threaded done in 10.476 seconds.
Indirect threaded done in 30.197 seconds.

@svost
Copy link

svost commented Nov 8, 2016

model name : Intel(R) Xeon(R) CPU E5405 @ 2.00GHz
$ g++-5 -O2 -std=c++11 dispatchtest_stack.cxx
$ ./a.out && ./a.out && ./a.out
Direct threaded done in 9.873 seconds.
Indirect threaded done in 12.187 seconds.
Direct threaded done in 9.833 seconds.
Indirect threaded done in 12.201 seconds.
Direct threaded done in 9.836 seconds.
Indirect threaded done in 12.197 seconds.
$ /opt/llvm-3.9.0/bin/clang++ -O2 -std=c++11 dispatchtest_stack.cxx
$ ./a.out && ./a.out && ./a.out
Direct threaded done in 7.48 seconds.
Indirect threaded done in 10.048 seconds.
Direct threaded done in 7.473 seconds.
Indirect threaded done in 10.052 seconds.
Direct threaded done in 7.479 seconds.
Indirect threaded done in 10.048 seconds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment