From 83b7efdd0329ee6a2470cdb1e67e40f0c143d921 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Thu, 6 Jan 2022 09:50:58 +0000 Subject: [PATCH] Use iterator, rather than index access for JSON data, if possible. Bit of a speed up! --- M6502/HarteTest_6502/checker_t.cpp | 50 +++++++++---------- M6502/HarteTest_6502/checker_t.h | 14 ++---- M6502/HarteTest_6502/opcode_test_suite_t.cpp | 7 +-- M6502/HarteTest_6502/opcode_test_suite_t.h | 7 +-- .../HarteTest_6502/processor_test_suite_t.cpp | 6 +-- M6502/HarteTest_6502/processor_test_suite_t.h | 12 +++-- M6502/HarteTest_6502/tests.cpp | 10 ++-- 7 files changed, 53 insertions(+), 53 deletions(-) diff --git a/M6502/HarteTest_6502/checker_t.cpp b/M6502/HarteTest_6502/checker_t.cpp index 6c51dd5..495c0ec 100644 --- a/M6502/HarteTest_6502/checker_t.cpp +++ b/M6502/HarteTest_6502/checker_t.cpp @@ -91,12 +91,12 @@ bool checker_t::check(const std::string what, const uint16_t address, const uint checker_t::checker_t(TestRunner& runner) : m_runner(runner) {} -void checker_t::initialiseState() { +void checker_t::initialiseState(const test_t test) { auto& cpu = runner().CPU(); auto& ram = runner().RAM(); - const auto initial = test().initial(); + const auto initial = test.initial(); cpu.PC().word = initial.pc(); cpu.S() = initial.s(); @@ -105,10 +105,10 @@ void checker_t::initialiseState() { cpu.Y() = initial.y(); cpu.P() = initial.p(); for (const auto entry : initial.ram()) { - const byte_t byte(entry); - const auto address = byte.address(); - const auto value = byte.value(); - ram.poke(address, value); + auto data = entry.begin(); + const int64_t address = (*data).get_int64(); + const int64_t value = (*++data).get_int64(); + ram.poke((uint16_t)address, (uint8_t)value); } } @@ -130,12 +130,12 @@ void checker_t::initialise() { } // -bool checker_t::checkState() { +bool checker_t::checkState(test_t test) { auto& cpu = runner().CPU(); auto& ram = runner().RAM(); - const auto expected_cycles = test().cycles(); + const auto expected_cycles = test.cycles(); const auto& actual_cycles = m_actualCycles; m_cycle_count_mismatch = expected_cycles.size() != actual_cycles.size(); if (m_cycle_count_mismatch) @@ -144,23 +144,23 @@ bool checker_t::checkState() { size_t actual_idx = 0; for (const auto expected_cycle : expected_cycles) { - const auto expected = cycle_t(expected_cycle); + auto expected_data = expected_cycle.begin(); const auto& actual = actual_cycles.at(actual_idx++); // actual could be less than expected - const auto expected_address = expected.address(); + const int64_t expected_address = (*expected_data).get_int64(); const auto actual_address = std::get<0>(actual); - check("Cycle address", expected_address, actual_address); + check("Cycle address", (uint16_t)expected_address, actual_address); - const auto expected_value = expected.value(); + const int64_t expected_value = (*++expected_data).get_int64(); const auto actual_value = std::get<1>(actual); - check("Cycle value", expected_value, actual_value); + check("Cycle value", (uint8_t)expected_value, actual_value); - const auto expected_action = expected.action(); + const std::string_view expected_action = (*++expected_data).get_string(); const auto& actual_action = std::get<2>(actual); check("Cycle action", expected_action, std::string_view(actual_action)); } - const auto final = test().final(); + const auto final = test.final(); const auto pc_good = check("PC", final.pc(), cpu.PC().word); const auto s_good = check("S", final.s(), cpu.S()); const auto a_good = check("A", final.a(), cpu.A()); @@ -170,9 +170,9 @@ bool checker_t::checkState() { bool ram_problem = false; for (const auto entry : final.ram()) { - const byte_t byte(entry); - const auto address = byte.address(); - const auto value = byte.value(); + auto data = entry.begin(); + const int64_t address = (*data).get_int64(); + const int64_t value = (*++data).get_int64(); const auto ram_good = check("RAM", address, value, ram.peek(address)); if (!ram_good && !ram_problem) ram_problem = true; @@ -196,9 +196,7 @@ void checker_t::disassemble(uint16_t address) { pushCurrentMessage(); } -void checker_t::check(test_t current) { - - m_test = current; +void checker_t::check(test_t test) { auto& cpu = runner().CPU(); @@ -206,7 +204,7 @@ void checker_t::check(test_t current) { m_actualCycles.clear(); runner().raisePOWER(); - initialiseState(); + initialiseState(test); const auto pc = cpu.PC().word; const auto start_opcode = runner().peek(pc); @@ -224,7 +222,7 @@ void checker_t::check(test_t current) { m_cycles = cpu.step(); runner().lowerPOWER(); - m_valid = checkState(); + m_valid = checkState(test); if (unimplemented()) { m_messages.push_back("Unimplemented"); @@ -235,7 +233,7 @@ void checker_t::check(test_t current) { disassemble(pc); - const auto final = test().final(); + const auto final = test.final(); raise("PC", final.pc(), cpu.PC().word); raise("S", final.s(), cpu.S()); raise("A", final.a(), cpu.A()); @@ -246,11 +244,11 @@ void checker_t::check(test_t current) { os() << std::dec << std::setfill(' ') << "Stepped cycles: " << cycles() - << ", expected events: " << test().cycles().size() + << ", expected events: " << test.cycles().size() << ", actual events: " << m_actualCycles.size(); pushCurrentMessage(); - dumpCycles("-- Expected cycles", test().cycles()); + dumpCycles("-- Expected cycles", test.cycles()); dumpCycles("-- Actual cycles", m_actualCycles); } } diff --git a/M6502/HarteTest_6502/checker_t.h b/M6502/HarteTest_6502/checker_t.h index af49947..d5a8193 100644 --- a/M6502/HarteTest_6502/checker_t.h +++ b/M6502/HarteTest_6502/checker_t.h @@ -21,8 +21,6 @@ private: EightBit::Symbols m_symbols; EightBit::Disassembly m_disassembler = { m_runner, m_runner.CPU(), m_symbols }; - test_t m_test; - std::ostringstream m_os; std::vector m_messages; @@ -35,12 +33,12 @@ private: bool m_valid = true; bool m_undocumented = false; - [[nodiscard]] auto& os() { return m_os; } + [[nodiscard]] constexpr auto& os() noexcept { return m_os; } - [[nodiscard]] auto& runner() noexcept { return m_runner; } + [[nodiscard]] constexpr auto& runner() noexcept { return m_runner; } void seedUndocumentedOpcodes(); - [[nodiscard]] bool checkState(); + [[nodiscard]] bool checkState(test_t test); void pushCurrentMessage(); @@ -84,9 +82,7 @@ private: void dumpCycles(const actual_cycles_t& cycles); void dumpCycle(const actual_cycle_t& cycle); - [[nodiscard]] auto test() const noexcept { return m_test; } - - void initialiseState(); + void initialiseState(test_t test); public: checker_t(TestRunner& runner); @@ -103,5 +99,5 @@ public: void initialise(); - void check(test_t current); + void check(test_t test); }; diff --git a/M6502/HarteTest_6502/opcode_test_suite_t.cpp b/M6502/HarteTest_6502/opcode_test_suite_t.cpp index 77944bd..cccac23 100644 --- a/M6502/HarteTest_6502/opcode_test_suite_t.cpp +++ b/M6502/HarteTest_6502/opcode_test_suite_t.cpp @@ -6,19 +6,20 @@ opcode_test_suite_t::opcode_test_suite_t(const std::string path) noexcept #ifdef USE_COROUTINES #if __cplusplus >= 202002L -EightBit::co_generator_t opcode_test_suite_t::generator() { +EightBit::co_generator_t opcode_test_suite_t::generator() const { for (const auto element : *this) co_yield test_t(element); } #else -void opcode_test_suite_t::generator(boost::coroutines2::coroutine::push_type& sink) { +void opcode_test_suite_t::generator(boost::coroutines2::coroutine::push_type& sink) const { for (const auto element : *this) sink(test_t(element)); } #endif #else -std::vector opcode_test_suite_t::generate() { +std::vector opcode_test_suite_t::generate() const { std::vector returned; + returned.reserve(size()); for (const auto element : *this) returned.push_back(test_t(element)); return returned; diff --git a/M6502/HarteTest_6502/opcode_test_suite_t.h b/M6502/HarteTest_6502/opcode_test_suite_t.h index 36c42b1..c2acb27 100644 --- a/M6502/HarteTest_6502/opcode_test_suite_t.h +++ b/M6502/HarteTest_6502/opcode_test_suite_t.h @@ -24,14 +24,15 @@ public: [[nodiscard]] auto begin() const noexcept { return array().begin(); } [[nodiscard]] auto end() const noexcept { return array().end(); } + [[nodiscard]] auto size() const noexcept { return array().size(); } #ifdef USE_COROUTINES #if __cplusplus >= 202002L - [[nodiscard]] EightBit::co_generator_t generator(); + [[nodiscard]] EightBit::co_generator_t generator() const; #else - void generator(boost::coroutines2::coroutine::push_type& sink); + void generator(boost::coroutines2::coroutine::push_type& sink) const; #endif #else - std::vector generate(); + std::vector generate() const; #endif }; diff --git a/M6502/HarteTest_6502/processor_test_suite_t.cpp b/M6502/HarteTest_6502/processor_test_suite_t.cpp index bc38c7c..2001dfc 100644 --- a/M6502/HarteTest_6502/processor_test_suite_t.cpp +++ b/M6502/HarteTest_6502/processor_test_suite_t.cpp @@ -9,20 +9,20 @@ processor_test_suite_t::processor_test_suite_t(std::string location) noexcept #ifdef USE_COROUTINES #if __cplusplus >= 202002L -EightBit::co_generator_t processor_test_suite_t::generator() { +EightBit::co_generator_t processor_test_suite_t::generator() const { std::filesystem::path directory = location(); for (const auto& entry : std::filesystem::directory_iterator{ directory }) co_yield opcode_test_suite_t(entry.path().string()); } #else -void processor_test_suite_t::generator(boost::coroutines2::coroutine::push_type& sink) { +void processor_test_suite_t::generator(boost::coroutines2::coroutine::push_type& sink) const { std::filesystem::path directory = location(); for (const auto& entry : std::filesystem::directory_iterator{ directory }) sink(opcode_test_suite_t(entry.path().string())); } #endif #else -std::vector processor_test_suite_t::generate() { +std::vector processor_test_suite_t::generate() const { std::vector returned; std::filesystem::path directory = location(); for (const auto& entry : std::filesystem::directory_iterator{ directory }) diff --git a/M6502/HarteTest_6502/processor_test_suite_t.h b/M6502/HarteTest_6502/processor_test_suite_t.h index 3d64cdc..2bdc3a7 100644 --- a/M6502/HarteTest_6502/processor_test_suite_t.h +++ b/M6502/HarteTest_6502/processor_test_suite_t.h @@ -22,15 +22,19 @@ private: public: processor_test_suite_t(std::string location) noexcept; - std::string_view location() const noexcept { return m_location; } +#if __cplusplus >= 202002L + [[nodiscard]] constexpr std::string_view location() const noexcept { return m_location; } +#else + [[nodiscard]] std::string_view location() const noexcept { return m_location; } +#endif #ifdef USE_COROUTINES #if __cplusplus >= 202002L - [[nodiscard]] EightBit::co_generator_t generator(); + [[nodiscard]] EightBit::co_generator_t generator() const; #else - void generator(boost::coroutines2::coroutine::push_type& sink); + void generator(boost::coroutines2::coroutine::push_type& sink) const; #endif #else - std::vector generate(); + [[nodiscard]] std::vector generate() const; #endif }; diff --git a/M6502/HarteTest_6502/tests.cpp b/M6502/HarteTest_6502/tests.cpp index f8c1403..75eab57 100644 --- a/M6502/HarteTest_6502/tests.cpp +++ b/M6502/HarteTest_6502/tests.cpp @@ -66,7 +66,7 @@ int main() { #else - processor_test_suite_t m6502_tests(directory); + const processor_test_suite_t m6502_tests(directory); boost::coroutines2::coroutine::pull_type opcodes(boost::bind(&processor_test_suite_t::generator, &m6502_tests, _1)); for (auto& opcode : opcodes) { @@ -75,7 +75,7 @@ int main() { opcode.load(); boost::coroutines2::coroutine::pull_type tests(boost::bind(&opcode_test_suite_t::generator, &opcode, _1)); - for (auto& test : tests) { + for (const auto& test : tests) { checker.check(test); @@ -97,7 +97,7 @@ int main() { #else - processor_test_suite_t m6502_tests(directory); + const processor_test_suite_t m6502_tests(directory); auto opcodes = m6502_tests.generate(); for (auto& opcode : opcodes) { @@ -105,8 +105,8 @@ int main() { std::cout << "Processing: " << path.filename() << "\n"; opcode.load(); - auto tests = opcode.generate(); - for (auto& test : tests) { + const auto tests = opcode.generate(); + for (const auto& test : tests) { checker.check(test);