Skip to content

Commit

Permalink
#32 bench for Square equation
Browse files Browse the repository at this point in the history
  • Loading branch information
levBagryansky authored Oct 15, 2023
1 parent d1be322 commit 4ed08cd
Show file tree
Hide file tree
Showing 10 changed files with 284 additions and 54 deletions.
3 changes: 2 additions & 1 deletion bench/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ add_library(chai_benchif INTERFACE)
target_link_libraries(chai_benchif INTERFACE
chai_include
chai_interpreter
benchmark::benchmark
benchmark
)

add_executable(bench main_bench.cpp)
Expand All @@ -12,6 +12,7 @@ function(chai_bench SOURCE_NAME)
endfunction(chai_bench)

chai_bench(dummy_bench.cpp)
chai_bench(interpreter_bench.cpp)
target_link_libraries(bench PRIVATE chai_benchif)

add_custom_target(run_bench
Expand Down
42 changes: 42 additions & 0 deletions bench/codeman-wrapper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once

#include "ChaiVM/interpreter/executor.hpp"

using namespace chai::interpreter;

class CodeManWrapper {
public:
/*
* @todo #32:60min Make the methods "instr2Raw" implemented only once. For
* example in utils.
*/
static chai::bytecode_t instr2Raw(Operation op, RegisterId r1,
RegisterId r2) {
return (operation2opcode(op)) | (r1 << 8) | (r2 << 16);
}
static chai::bytecode_t instr2Raw(Operation op, Immidiate imm) {
return (operation2opcode(op)) |
(static_cast<chai::bytecode_t>(imm) << 8);
}
static chai::bytecode_t instr2Raw(Operation op) {
return (operation2opcode(op));
}

public:
void load(Operation op, RegisterId r1, RegisterId r2) {
manager_.load(instr2Raw(op, r1, r2));
}

void load(Operation op, Immidiate imm) {
manager_.load(instr2Raw(op, imm));
}

void load(Operation op) { manager_.load(instr2Raw(op)); }

static uint8_t operation2opcode(Operation operation) {
return (uint8_t)operation;
}

public:
CodeManager manager_;
};
88 changes: 88 additions & 0 deletions bench/interpreter_bench.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <benchmark/benchmark.h>

#include "codeman-wrapper.hpp"

using namespace chai::interpreter;

static void initCode(CodeManWrapper &codeman);

static void BM_SquareEquation(benchmark::State &state) {
// Perform setup here
CodeManWrapper wrapper{};
initCode(wrapper);
Executor executor{&wrapper.manager_};
for (auto _ : state) {
executor.run();
executor.restart();
}
}
// Register the function as a benchmark
// @todo #32:60min Measure mips here
BENCHMARK(BM_SquareEquation);

static void initCode(CodeManWrapper &codeman) {
const RegisterId r1 = 1;
const RegisterId r2 = 2;
const RegisterId r3 = 3;
const RegisterId r4 = 4;
const RegisterId r5 = 5;
const RegisterId r6 = 6;
const RegisterId r7 = 7;
const RegisterId r8 = 8;
const RegisterId r9 = 9;
const RegisterId r10 = 10;
const RegisterId r11 = 11;

// r1 = 1.0, r2 = -5.0, r3 = 6.0
codeman.load(Ldiaf, std::bit_cast<Immidiate>(1.0f));
codeman.load(Star, r1, 0);
codeman.load(Ldiaf, std::bit_cast<Immidiate>(-5.0f));
codeman.load(Star, r2, 0);
codeman.load(Ldiaf, std::bit_cast<Immidiate>(+6.0f));
codeman.load(Star, r3, 0);

// r4 = -4*r1*r3
codeman.load(Ldiaf, std::bit_cast<Immidiate>(-4.0f));
codeman.load(Mulf, r1, 0);
codeman.load(Mulf, r3, 0);
codeman.load(Star, r4, 0);

// r5 = b * b
codeman.load(Ldra, r2, 0);
codeman.load(Mulf, r2, 0);
codeman.load(Star, r5, 0);

// r6 = r5 + r4
codeman.load(Ldra, r5, 0);
codeman.load(Addf, r4, 0);
codeman.load(Star, r6, 0);

// r6 = sqrt(r6)
codeman.load(Ldra, r6, 0);
codeman.load(IcSqrt);
codeman.load(Star, r6, 0);

// r7 = 2a
codeman.load(Ldra, r1, 0);
codeman.load(chai::interpreter::Mulif, std::bit_cast<Immidiate>(2.0f));
codeman.load(Star, r7);

// r8 = r6 - r2
codeman.load(Ldra, r6, 0);
codeman.load(Subf, r2, 0);
codeman.load(Star, r8, 0);

// X1 = r9 = r8 / r7
codeman.load(Ldra, r8, 0);
codeman.load(Divf, r7, 0);
codeman.load(Star, r9, 0);

// acc = -r2 - r6
// r11 = acc / r7
codeman.load(Ldiaf, std::bit_cast<Immidiate>(0.0f));
codeman.load(Subf, r2, 0);
codeman.load(Subf, r6, 0);
codeman.load(Divf, r7, 0);
codeman.load(Star, r11, 0);
codeman.load(Ret);
}
5 changes: 0 additions & 5 deletions include/ChaiVM/interpreter/code-manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ class CodeManager {

void load(std::istream &istream);

/**
* Parses file by path and loads its code.
* @param path Path of file to load.
* @todo #8:90min Implement the method below.
*/
void load(const std::filesystem::path &path);

bytecode_t getBytecode(chsize_t pc);
Expand Down
1 change: 1 addition & 0 deletions include/ChaiVM/interpreter/executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Executor {

Executor(CodeManager *manager);
void run();
void restart();
const RegisterFile &getState() const &;

private:
Expand Down
3 changes: 3 additions & 0 deletions include/ChaiVM/interpreter/reg-file.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <cstdio>

#include <array>
#include <cstdlib>
Expand All @@ -21,6 +22,8 @@ class RegisterFile {

static constexpr size_t Size = std::numeric_limits<RegisterId>::max();

void dump();

private:
chsize_t acc_;
chsize_t pc_;
Expand Down
3 changes: 2 additions & 1 deletion src/ChaiVM/interpreter/code-manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ bytecode_t CodeManager::getBytecode(chsize_t pc) {
pc % sizeof(bytecode_t) != 0) {
throw BeyondCodeBoundaries(
"Going beyond the boundaries of the code at pc: " +
std::to_string(pc));
std::to_string(pc) + " / " +
std::to_string(raw_.size() * sizeof(bytecode_t)));
} else {
return raw_[pc / sizeof(bytecode_t)];
}
Expand Down
49 changes: 25 additions & 24 deletions src/ChaiVM/interpreter/executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace chai::interpreter {
Executor::Executor(CodeManager *manager)
: codeManager_(manager), regFile_(codeManager_->startPC()) {}
void Executor::run() { DO_NEXT_INS() }
void Executor::restart() { regFile_.pc() = codeManager_->startPC(); }
const RegisterFile &Executor::getState() const & { return regFile_; }
void Executor::inv(Instruction ins) {
throw InvalidInstruction("Invalid operation at pc: " +
Expand Down Expand Up @@ -57,12 +58,12 @@ void Executor::addi(Instruction ins) {
DO_NEXT_INS()
}
void Executor::sub(Instruction ins) {
regFile_.acc() = regFile_[ins.r1] - regFile_.acc();
regFile_.acc() -= regFile_[ins.r1];
advancePc();
DO_NEXT_INS()
}
void Executor::subi(Instruction ins) {
regFile_.acc() = ins.immidiate - regFile_.acc();
regFile_.acc() -= ins.immidiate;
advancePc();
DO_NEXT_INS()
}
Expand All @@ -77,12 +78,12 @@ void Executor::muli(Instruction ins) {
DO_NEXT_INS()
}
void Executor::div(Instruction ins) {
regFile_.acc() = regFile_[ins.r1] / regFile_.acc();
regFile_.acc() /= regFile_[ins.r1];
advancePc();
DO_NEXT_INS()
}
void Executor::divi(Instruction ins) {
regFile_.acc() = ins.immidiate / regFile_.acc();
regFile_.acc() /= ins.immidiate;
advancePc();
DO_NEXT_INS()
}
Expand All @@ -94,58 +95,58 @@ void Executor::ldiaf(Instruction ins) {
}

void Executor::addf(Instruction ins) {
double sum = std::bit_cast<double>(regFile_[ins.r1]) +
double res = std::bit_cast<double>(regFile_[ins.r1]) +
std::bit_cast<double>(regFile_.acc());
regFile_.acc() = std::bit_cast<chsize_t>(sum);
regFile_.acc() = std::bit_cast<chsize_t>(res);
advancePc();
DO_NEXT_INS()
}
void Executor::addif(Instruction ins) {
double sum = static_cast<double>(std::bit_cast<float>(ins.immidiate)) +
double res = static_cast<double>(std::bit_cast<float>(ins.immidiate)) +
std::bit_cast<double>(regFile_.acc());
regFile_.acc() = std::bit_cast<chsize_t>(sum);
regFile_.acc() = std::bit_cast<chsize_t>(res);
advancePc();
DO_NEXT_INS()
}
void Executor::subf(Instruction ins) {
double dif = std::bit_cast<double>(regFile_[ins.r1]) -
std::bit_cast<double>(regFile_.acc());
regFile_.acc() = std::bit_cast<chsize_t>(dif);
double res = std::bit_cast<double>(regFile_.acc()) -
std::bit_cast<double>(regFile_[ins.r1]);
regFile_.acc() = std::bit_cast<chsize_t>(res);
advancePc();
DO_NEXT_INS()
}
void Executor::subif(Instruction ins) {
double dif = static_cast<double>(std::bit_cast<float>(ins.immidiate)) -
std::bit_cast<double>(regFile_.acc());
regFile_.acc() = std::bit_cast<chsize_t>(dif);
double res = std::bit_cast<double>(regFile_.acc()) -
static_cast<double>(std::bit_cast<float>(ins.immidiate));
regFile_.acc() = std::bit_cast<chsize_t>(res);
advancePc();
DO_NEXT_INS()
}
void Executor::mulf(Instruction ins) {
double sum = std::bit_cast<double>(regFile_[ins.r1]) *
double res = std::bit_cast<double>(regFile_[ins.r1]) *
std::bit_cast<double>(regFile_.acc());
regFile_.acc() = std::bit_cast<chsize_t>(sum);
regFile_.acc() = std::bit_cast<chsize_t>(res);
advancePc();
DO_NEXT_INS()
}
void Executor::mulif(Instruction ins) {
double dif = static_cast<double>(std::bit_cast<float>(ins.immidiate)) *
double res = static_cast<double>(std::bit_cast<float>(ins.immidiate)) *
std::bit_cast<double>(regFile_.acc());
regFile_.acc() = std::bit_cast<chsize_t>(dif);
regFile_.acc() = std::bit_cast<chsize_t>(res);
advancePc();
DO_NEXT_INS()
}
void Executor::divf(Instruction ins) {
double sum = std::bit_cast<double>(regFile_[ins.r1]) /
std::bit_cast<double>(regFile_.acc());
regFile_.acc() = std::bit_cast<chsize_t>(sum);
double res = std::bit_cast<double>(regFile_.acc()) /
std::bit_cast<double>(regFile_[ins.r1]);
regFile_.acc() = std::bit_cast<chsize_t>(res);
advancePc();
DO_NEXT_INS()
}
void Executor::divif(Instruction ins) {
double dif = static_cast<double>(std::bit_cast<float>(ins.immidiate)) /
std::bit_cast<double>(regFile_.acc());
regFile_.acc() = std::bit_cast<chsize_t>(dif);
double res = std::bit_cast<double>(regFile_.acc()) /
static_cast<double>(std::bit_cast<float>(ins.immidiate));
regFile_.acc() = std::bit_cast<chsize_t>(res);
advancePc();
DO_NEXT_INS()
}
Expand Down
17 changes: 16 additions & 1 deletion src/ChaiVM/interpreter/reg-file.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "ChaiVM/interpreter/reg-file.hpp"
#include <bit>
#include <cassert>
#include <iostream>

namespace chai::interpreter {

Expand All @@ -15,6 +17,19 @@ chai::chsize_t &RegisterFile::pc() { return pc_; }
chai::chsize_t RegisterFile::pc() const { return pc_; }
chai::chsize_t &RegisterFile::acc() { return acc_; }
chai::chsize_t RegisterFile::acc() const { return acc_; }
RegisterFile::RegisterFile(chsize_t pc) : pc_(pc) {}
RegisterFile::RegisterFile(chsize_t pc) : pc_(pc), acc_(0), registers_{} {}

void RegisterFile::dump() {
std::cout << "pc = " << pc_ << ", acc = " << std::bit_cast<int64_t>(acc_)
<< " = " << std::bit_cast<double>(acc_) << std::endl;
for (int i = 0; i < Size; ++i) {
if (registers_[i] != 0) {
std::cout << "rf[" << i
<< "] = " << std::bit_cast<int64_t>(registers_[i])
<< " = " << std::bit_cast<double>(registers_[i])
<< std::endl;
}
}
std::cout << std::endl;
}
} // namespace chai::interpreter
Loading

3 comments on commit 4ed08cd

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on 4ed08cd Oct 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 8-cc9cbab0 disappeared from include/ChaiVM/interpreter/code-manager.hpp), that's why I closed #18. Please, remember that the puzzle was not necessarily removed in this particular commit. Maybe it happened earlier, but we discovered this fact only now.

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on 4ed08cd Oct 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 32-cab74994 discovered in bench/codeman-wrapper.hpp) and submitted as #34. Please, remember that the puzzle was not necessarily added in this particular commit. Maybe it was added earlier, but we discovered it only now.

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on 4ed08cd Oct 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 32-e5a361e3 discovered in bench/interpreter_bench.cpp) and submitted as #35. Please, remember that the puzzle was not necessarily added in this particular commit. Maybe it was added earlier, but we discovered it only now.

Please sign in to comment.