Browse Source

perf: AllCases module

legacy
Dnomd343 2 years ago
parent
commit
cc521f2331
  1. 56
      src/all_cases/all_cases.cc
  2. 15
      src/all_cases/all_cases.h
  3. 4
      src/all_cases/basic_ranges.cc
  4. 3
      src/all_cases/basic_ranges.h
  5. 11
      src/main.cc

56
src/all_cases/all_cases.cc

@ -1,47 +1,51 @@
#include "common.h" #include "common.h"
#include "all_cases.h" #include "all_cases.h"
std::mutex AllCases::all_cases_building; std::mutex AllCases::building;
bool AllCases::all_cases_available = false; bool AllCases::available = false;
std::vector<uint32_t> AllCases::all_cases[]; std::vector<uint32_t> AllCases::data[];
AllCases::Status AllCases::status() { // get all cases status AllCases::Status AllCases::status() { // get all cases status
if (all_cases_available) { if (AllCases::available) {
return AVAILABLE; // all cases already built return AVAILABLE; // all cases already built
} }
if (!all_cases_building.try_lock()) { // fail to lock mutex -> another thread working if (!AllCases::building.try_lock()) { // fail to lock mutex
return BUILDING; return BUILDING; // another thread working
} }
all_cases_building.unlock(); // release mutex AllCases::building.unlock(); // release mutex
return NO_INIT; return NO_INIT;
} }
const std::vector<uint32_t> (*AllCases::fetch())[16] { // get const ptr of all cases const std::vector<uint32_t> (*AllCases::fetch())[16] { // get all cases content
if (status() != AllCases::AVAILABLE) { if (status() != AVAILABLE) {
AllCases::build(); // all cases initialize AllCases::build(); // all cases initialize
} }
return &all_cases; // return ptr return &AllCases::data; // return const ptr
} }
void AllCases::build() { // build all cases void AllCases::build() { // ensure that all cases available
if (AllCases::all_cases_available) { if (!AllCases::available) {
return; // all cases already built if (AllCases::building.try_lock()) { // mutex lock success
build_data(); // start build process
AllCases::available = true; // set available flag
} else {
AllCases::building.lock(); // blocking waiting
}
AllCases::building.unlock();
} }
if (AllCases::all_cases_building.try_lock()) { // lock success -> start building }
void AllCases::build_data() { // find all cases
for (uint32_t head = 0; head < 16; ++head) { // address of 2x2 block
if ((head & 0b11) == 0b11) {
continue; // invalid 2x2 address
}
/// head -> 0/1/2 / 4/5/6 / 8/9/10 / 12/13/14 /// head -> 0/1/2 / 4/5/6 / 8/9/10 / 12/13/14
for (uint32_t head = 0; head < 16; ++head) { // address of 2x2 block data[head].reserve(ALL_CASES_SIZE[head]); // memory pre-allocated
if ((head & 0b11) == 0b11) { for (auto const &range : *BasicRanges::fetch()) { // check base on 2x2 address and range
continue; // invalid 2x2 address if (Common::check_case(head, range)) {
} data[head].emplace_back(Common::range_reverse(range)); // found valid case
for (uint32_t const &range : *BasicRanges::fetch()) { // check base on 2x2 address and range
if (Common::check_case(head, range)) {
all_cases[head].emplace_back(Common::range_reverse(range)); // found valid case
}
} }
} }
AllCases::all_cases_available = true; // set available flag
} else { // another thread building
AllCases::all_cases_building.lock(); // blocking waiting
} }
AllCases::all_cases_building.unlock();
} }

15
src/all_cases/all_cases.h

@ -5,6 +5,13 @@
#include <cstdint> #include <cstdint>
#include "basic_ranges.h" #include "basic_ranges.h"
const uint32_t ALL_CASES_SIZE[16] = {
2942906, 2260392, 2942906, 0,
2322050, 1876945, 2322050, 0,
2322050, 1876945, 2322050, 0,
2942906, 2260392, 2942906, 0,
};
class AllCases : public BasicRanges { class AllCases : public BasicRanges {
public: public:
static void build(); static void build();
@ -12,7 +19,9 @@ public:
static const std::vector<uint32_t> (*fetch())[16]; static const std::vector<uint32_t> (*fetch())[16];
private: private:
static bool all_cases_available; static bool available;
static std::mutex all_cases_building; static std::mutex building;
static std::vector<uint32_t> all_cases[16]; static std::vector<uint32_t> data[16];
static void build_data();
}; };

4
src/all_cases/basic_ranges.cc

@ -26,7 +26,7 @@ BasicRanges::Status BasicRanges::status() { // get basic ranges status
return NO_INIT; return NO_INIT;
} }
const std::vector<uint32_t>* BasicRanges::fetch() { // get const ptr of basic ranges const std::vector<uint32_t>* BasicRanges::fetch() { // get basic ranges content
if (status() != AVAILABLE) { if (status() != AVAILABLE) {
BasicRanges::build(); // basic ranges initialize BasicRanges::build(); // basic ranges initialize
} }
@ -46,7 +46,7 @@ void BasicRanges::build() { // ensure that basic ranges available
} }
void BasicRanges::build_data() { // build basic ranges void BasicRanges::build_data() { // build basic ranges
BasicRanges::data.reserve(DATA_SIZE); // pre-allocated memory BasicRanges::data.reserve(BASIC_RANGES_SIZE); // memory pre-allocated
for (int n = 0; n <= 7; ++n) { // number of 1x2 and 2x1 block -> 0 ~ 7 for (int n = 0; n <= 7; ++n) { // number of 1x2 and 2x1 block -> 0 ~ 7
for (int n_2x1 = 0; n_2x1 <= n; ++n_2x1) { // number of 2x1 block -> 0 ~ n for (int n_2x1 = 0; n_2x1 <= n; ++n_2x1) { // number of 2x1 block -> 0 ~ n
for (int n_1x1 = 0; n_1x1 <= (14 - n * 2); ++n_1x1) { // number of 1x1 block -> 0 ~ (14 - 2n) for (int n_1x1 = 0; n_1x1 <= (14 - n * 2); ++n_1x1) { // number of 1x1 block -> 0 ~ (14 - 2n)

3
src/all_cases/basic_ranges.h

@ -4,6 +4,8 @@
#include <vector> #include <vector>
#include <cstdint> #include <cstdint>
const uint32_t BASIC_RANGES_SIZE = 7311921;
class BasicRanges { class BasicRanges {
public: public:
enum Status { enum Status {
@ -19,7 +21,6 @@ private:
static bool available; static bool available;
static std::mutex building; static std::mutex building;
static std::vector<uint32_t> data; static std::vector<uint32_t> data;
static const uint32_t DATA_SIZE = 7311921;
static void build_data(); static void build_data();
static void generate(int n1, int n2, int n3, int n4); static void generate(int n1, int n2, int n3, int n4);

11
src/main.cc

@ -209,10 +209,19 @@ int main() {
// } // }
BasicRanges::build(); // BasicRanges::build();
// for (auto const &range : *BasicRanges::fetch()) { // for (auto const &range : *BasicRanges::fetch()) {
// printf("%08X\n", range); // printf("%08X\n", range);
// }
AllCases::build();
// for (uint32_t head = 0; head < 16; ++head) {
// uint64_t prefix = (uint64_t)head << 32;
// for (auto const &range : (*AllCases::fetch())[head]) {
// printf("%09lX\n", prefix | range);
// }
// } // }
std::cout << (clock() - start_time) * 1000 / CLOCKS_PER_SEC << "ms" << std::endl; std::cout << (clock() - start_time) * 1000 / CLOCKS_PER_SEC << "ms" << std::endl;

Loading…
Cancel
Save