summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bench/bench_window.cpp2
-rw-r--r--include/lib94/lib94.hpp1
-rw-r--r--lib94/core.cpp72
-rw-r--r--lib94/executors.cpp109
-rw-r--r--score/main.cpp2
-rw-r--r--tabulator-mpi/worker.cpp2
6 files changed, 102 insertions, 86 deletions
diff --git a/bench/bench_window.cpp b/bench/bench_window.cpp
index 767198b..7393e9f 100644
--- a/bench/bench_window.cpp
+++ b/bench/bench_window.cpp
@@ -115,7 +115,7 @@ const lib94::warrior *bench_window::do_step() {
last_core_step_distance = time - last_core_step_start;
last_core_step_start = time;
- const lib94::warrior *result = lib94::single_step();
+ const lib94::warrior *result = lib94::single_step<true>();
core.mut.lock();
core.age_all();
diff --git a/include/lib94/lib94.hpp b/include/lib94/lib94.hpp
index eeb53ec..18f90b4 100644
--- a/include/lib94/lib94.hpp
+++ b/include/lib94/lib94.hpp
@@ -92,6 +92,7 @@ namespace lib94 {
//assumes that there is a next warrior
//returns a warrior if it dies
+ template <bool update_address_sets>
const warrior *single_step();
}
diff --git a/lib94/core.cpp b/lib94/core.cpp
index 49b76e5..a19e6b7 100644
--- a/lib94/core.cpp
+++ b/lib94/core.cpp
@@ -48,10 +48,6 @@ namespace lib94 {
read_addresses.insert(instr - core);
}
- void add_executed_instruction(const instruction *instr) {
- executed_addresses.insert(instr - core);
- }
-
struct warrior_info {
const warrior *the_warrior;
std::deque<number_t> processes;
@@ -226,37 +222,42 @@ namespace lib94 {
}
}
- template<opcode op, modifier mod>
+ template<opcode op, modifier mod, bool uas>
bool execute();
- #define EXECUTOR_DECL_LINE(mod) \
- extern template bool execute<DAT, mod>(); extern template bool execute<MOV, mod>(); \
- extern template bool execute<ADD, mod>(); extern template bool execute<SUB, mod>(); \
- extern template bool execute<MUL, mod>(); extern template bool execute<DIV, mod>(); \
- extern template bool execute<MOD, mod>(); extern template bool execute<JMP, mod>(); \
- extern template bool execute<JMZ, mod>(); extern template bool execute<JMN, mod>(); \
- extern template bool execute<DJN, mod>(); extern template bool execute<SEQ, mod>(); \
- extern template bool execute<SNE, mod>(); extern template bool execute<SLT, mod>(); \
- extern template bool execute<SPL, mod>(); extern template bool execute<NOP, mod>();
-
- EXECUTOR_DECL_LINE(A)
- EXECUTOR_DECL_LINE(B)
- EXECUTOR_DECL_LINE(AB)
- EXECUTOR_DECL_LINE(BA)
- EXECUTOR_DECL_LINE(F)
- EXECUTOR_DECL_LINE(X)
- EXECUTOR_DECL_LINE(I)
+ #define EXECUTOR_DECL_LINE(mod, uas) \
+ extern template bool execute<DAT, mod, uas>(); extern template bool execute<MOV, mod, uas>(); \
+ extern template bool execute<ADD, mod, uas>(); extern template bool execute<SUB, mod, uas>(); \
+ extern template bool execute<MUL, mod, uas>(); extern template bool execute<DIV, mod, uas>(); \
+ extern template bool execute<MOD, mod, uas>(); extern template bool execute<JMP, mod, uas>(); \
+ extern template bool execute<JMZ, mod, uas>(); extern template bool execute<JMN, mod, uas>(); \
+ extern template bool execute<DJN, mod, uas>(); extern template bool execute<SEQ, mod, uas>(); \
+ extern template bool execute<SNE, mod, uas>(); extern template bool execute<SLT, mod, uas>(); \
+ extern template bool execute<SPL, mod, uas>(); extern template bool execute<NOP, mod, uas>();
+
+ #define EXECUTOR_DECL(uas) \
+ EXECUTOR_DECL_LINE(A, uas) \
+ EXECUTOR_DECL_LINE(B, uas) \
+ EXECUTOR_DECL_LINE(AB, uas) \
+ EXECUTOR_DECL_LINE(BA, uas) \
+ EXECUTOR_DECL_LINE(F, uas) \
+ EXECUTOR_DECL_LINE(X, uas) \
+ EXECUTOR_DECL_LINE(I, uas)
+
+ EXECUTOR_DECL(true)
+ EXECUTOR_DECL(false)
#define EXECUTOR_REF_LINE(mod) \
- &execute<DAT, mod>, &execute<MOV, mod>, \
- &execute<ADD, mod>, &execute<SUB, mod>, \
- &execute<MUL, mod>, &execute<DIV, mod>, \
- &execute<MOD, mod>, &execute<JMP, mod>, \
- &execute<JMZ, mod>, &execute<JMN, mod>, \
- &execute<DJN, mod>, &execute<SEQ, mod>, \
- &execute<SNE, mod>, &execute<SLT, mod>, \
- &execute<SPL, mod>, &execute<NOP, mod>
-
+ &execute<DAT, mod, uas>, &execute<MOV, mod, uas>, \
+ &execute<ADD, mod, uas>, &execute<SUB, mod, uas>, \
+ &execute<MUL, mod, uas>, &execute<DIV, mod, uas>, \
+ &execute<MOD, mod, uas>, &execute<JMP, mod, uas>, \
+ &execute<JMZ, mod, uas>, &execute<JMN, mod, uas>, \
+ &execute<DJN, mod, uas>, &execute<SEQ, mod, uas>, \
+ &execute<SNE, mod, uas>, &execute<SLT, mod, uas>, \
+ &execute<SPL, mod, uas>, &execute<NOP, mod, uas>
+
+ template <bool uas>
static const std::function<bool ()> executors[] = {
EXECUTOR_REF_LINE(A), EXECUTOR_REF_LINE(B),
EXECUTOR_REF_LINE(AB), EXECUTOR_REF_LINE(BA),
@@ -270,6 +271,7 @@ namespace lib94 {
this_warrior->processes.push_back(pc);
}
+ template <bool update_address_sets>
const warrior *single_step() {
this_warrior = alive_warriors.front();
alive_warriors.pop_front();
@@ -277,7 +279,8 @@ namespace lib94 {
program_counter = this_warrior->processes.front();
this_warrior->processes.pop_front();
- executed_addresses.insert(program_counter);
+ if constexpr (update_address_sets)
+ executed_addresses.insert(program_counter);
instruction_register = core[program_counter];
evaluate_operand(instruction_register.amode, instruction_register.anumber, a_pointer, a_instruction);
@@ -286,7 +289,7 @@ namespace lib94 {
a_instruction_writable = core + (program_counter + a_pointer) % LIB94_CORE_SIZE;
b_instruction_writable = core + (program_counter + b_pointer) % LIB94_CORE_SIZE;
- bool should_endeque = executors[instruction_register.op + instruction_register.mod * 16]();
+ bool should_endeque = executors<update_address_sets>[instruction_register.op + instruction_register.mod * 16]();
if (should_endeque)
this_warrior->processes.push_back((program_counter + 1) % LIB94_CORE_SIZE);
@@ -298,4 +301,7 @@ namespace lib94 {
return 0;
}
+ template const warrior *single_step<true>();
+ template const warrior *single_step<false>();
+
}
diff --git a/lib94/executors.cpp b/lib94/executors.cpp
index 236944b..12b371c 100644
--- a/lib94/executors.cpp
+++ b/lib94/executors.cpp
@@ -17,6 +17,11 @@ namespace lib94 {
void add_written_instruction(const instruction *instr);
void add_read_instruction(const instruction *instr);
+ #define maybe_add_written_instruction(instr) \
+ if constexpr (uas) add_written_instruction(instr)
+ #define maybe_add_read_instruction(instr) \
+ if constexpr (uas) add_read_instruction(instr)
+
struct single_target {
number_t *ptr;
@@ -154,7 +159,7 @@ namespace lib94 {
template<> struct target<X> : pair_target {};
template<> struct target<I> : instruction_target {};
- template<opcode op, modifier mod>
+ template<opcode op, modifier mod, bool uas>
bool execute() {
target<mod> dest_out;
target<mod> dest_in;
@@ -214,8 +219,8 @@ namespace lib94 {
return false;
else if constexpr (op == MOV) {
- add_read_instruction(a_instruction_writable);
- add_written_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_written_instruction(b_instruction_writable);
if constexpr (mod == I) {
dest_out.instr->op = src_in.instr->op;
dest_out.instr->mod = src_in.instr->mod;
@@ -229,36 +234,36 @@ namespace lib94 {
}
else if constexpr (op == ADD) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
- add_written_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
+ maybe_add_written_instruction(b_instruction_writable);
return dest_out.assign(dest_in, src_in, [](number_t a, number_t b) -> std::optional<number_t> {
return (a + b) % LIB94_CORE_SIZE;
});
}
else if constexpr (op == SUB) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
- add_written_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
+ maybe_add_written_instruction(b_instruction_writable);
return dest_out.assign(dest_in, src_in, [](number_t a, number_t b) -> std::optional<number_t> {
return (a + LIB94_CORE_SIZE - b) % LIB94_CORE_SIZE;
});
}
else if constexpr (op == MUL) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
- add_written_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
+ maybe_add_written_instruction(b_instruction_writable);
return dest_out.assign(dest_in, src_in, [](number_t a, number_t b) -> std::optional<number_t> {
return (a * b) % LIB94_CORE_SIZE;
});
}
else if constexpr (op == DIV) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
- add_written_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
+ maybe_add_written_instruction(b_instruction_writable);
return dest_out.assign(dest_in, src_in, [](number_t a, number_t b) -> std::optional<number_t> {
if (b == 0)
return {};
@@ -267,9 +272,9 @@ namespace lib94 {
}
else if constexpr (op == MOD) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
- add_written_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
+ maybe_add_written_instruction(b_instruction_writable);
return dest_out.assign(dest_in, src_in, [](number_t a, number_t b) -> std::optional<number_t> {
if (b == 0)
return {};
@@ -278,62 +283,62 @@ namespace lib94 {
}
else if constexpr (op == JMP) {
- add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
program_counter = (a_instruction_writable - core + LIB94_CORE_SIZE - 1) % LIB94_CORE_SIZE;
return true;
}
else if constexpr (op == JMZ) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
if (dest_in.is_zero())
program_counter = (a_instruction_writable - core + LIB94_CORE_SIZE - 1) % LIB94_CORE_SIZE;
return true;
}
else if constexpr (op == JMN) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
if (!dest_in.is_zero())
program_counter = (a_instruction_writable - core + LIB94_CORE_SIZE - 1) % LIB94_CORE_SIZE;
return true;
}
else if constexpr (op == DJN) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
- add_written_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
+ maybe_add_written_instruction(b_instruction_writable);
if (dest_out.dec_not_zero())
program_counter = (a_instruction_writable - core + LIB94_CORE_SIZE - 1) % LIB94_CORE_SIZE;
return true;
}
else if constexpr (op == SEQ) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
if (src_in.equal_to(dest_in))
program_counter = (program_counter + 1) % LIB94_CORE_SIZE;
return true;
}
else if constexpr (op == SNE) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
if (!src_in.equal_to(dest_in))
program_counter = (program_counter + 1) % LIB94_CORE_SIZE;
return true;
}
else if constexpr (op == SLT) {
- add_read_instruction(a_instruction_writable);
- add_read_instruction(b_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(b_instruction_writable);
if (src_in.less_than(dest_in))
program_counter = (program_counter + 1) % LIB94_CORE_SIZE;
return true;
}
else if constexpr (op == SPL) {
- add_read_instruction(a_instruction_writable);
+ maybe_add_read_instruction(a_instruction_writable);
enqueue_process((program_counter + 1) % LIB94_CORE_SIZE);
program_counter = (a_instruction_writable - core + LIB94_CORE_SIZE - 1) % LIB94_CORE_SIZE;
return true;
@@ -345,22 +350,26 @@ namespace lib94 {
else assert(false);
}
- #define EXECUTOR_INST_LINE(mod) \
- template bool execute<DAT, mod>(); template bool execute<MOV, mod>(); \
- template bool execute<ADD, mod>(); template bool execute<SUB, mod>(); \
- template bool execute<MUL, mod>(); template bool execute<DIV, mod>(); \
- template bool execute<MOD, mod>(); template bool execute<JMP, mod>(); \
- template bool execute<JMZ, mod>(); template bool execute<JMN, mod>(); \
- template bool execute<DJN, mod>(); template bool execute<SEQ, mod>(); \
- template bool execute<SNE, mod>(); template bool execute<SLT, mod>(); \
- template bool execute<SPL, mod>(); template bool execute<NOP, mod>();
-
- EXECUTOR_INST_LINE(A)
- EXECUTOR_INST_LINE(B)
- EXECUTOR_INST_LINE(AB)
- EXECUTOR_INST_LINE(BA)
- EXECUTOR_INST_LINE(F)
- EXECUTOR_INST_LINE(X)
- EXECUTOR_INST_LINE(I)
+ #define EXECUTOR_INST_LINE(mod, uas) \
+ template bool execute<DAT, mod, uas>(); template bool execute<MOV, mod, uas>(); \
+ template bool execute<ADD, mod, uas>(); template bool execute<SUB, mod, uas>(); \
+ template bool execute<MUL, mod, uas>(); template bool execute<DIV, mod, uas>(); \
+ template bool execute<MOD, mod, uas>(); template bool execute<JMP, mod, uas>(); \
+ template bool execute<JMZ, mod, uas>(); template bool execute<JMN, mod, uas>(); \
+ template bool execute<DJN, mod, uas>(); template bool execute<SEQ, mod, uas>(); \
+ template bool execute<SNE, mod, uas>(); template bool execute<SLT, mod, uas>(); \
+ template bool execute<SPL, mod, uas>(); template bool execute<NOP, mod, uas>();
+
+ #define EXECUTOR_INST(uas) \
+ EXECUTOR_INST_LINE(A, uas) \
+ EXECUTOR_INST_LINE(B, uas) \
+ EXECUTOR_INST_LINE(AB, uas) \
+ EXECUTOR_INST_LINE(BA, uas) \
+ EXECUTOR_INST_LINE(F, uas) \
+ EXECUTOR_INST_LINE(X, uas) \
+ EXECUTOR_INST_LINE(I, uas)
+
+ EXECUTOR_INST(true)
+ EXECUTOR_INST(false)
}
diff --git a/score/main.cpp b/score/main.cpp
index fa646d0..aae9ba2 100644
--- a/score/main.cpp
+++ b/score/main.cpp
@@ -85,7 +85,7 @@ int main(int argc, const char **argv) {
for (unsigned step_number = 0; step_number < steps_until_tie; ++step_number) {
- const lib94::warrior *w = lib94::single_step();
+ const lib94::warrior *w = lib94::single_step<false>();
if (w == ws[0]) {
++w2_wins;
diff --git a/tabulator-mpi/worker.cpp b/tabulator-mpi/worker.cpp
index e9768b2..47b8eeb 100644
--- a/tabulator-mpi/worker.cpp
+++ b/tabulator-mpi/worker.cpp
@@ -15,7 +15,7 @@ static int do_round(const lib94::warrior *w1, const lib94::warrior *w2) {
lib94::init_round(ws, 2);
for (int i = 0; i < 1000000; ++i) {
- const lib94::warrior *result = lib94::single_step();
+ const lib94::warrior *result = lib94::single_step<false>();
if (result == w1)
return -1;
if (result == w2)