Browse Source

perf: speed up calculation

master
Dnomd343 3 weeks ago
parent
commit
9cb07afd0f
  1. 2
      src/core/CMakeLists.txt
  2. 162
      src/core/fast_cal/internal/demo.cc

2
src/core/CMakeLists.txt

@ -37,7 +37,7 @@ set(KLOTSKI_CORE_SRC
add_library(klotski_core STATIC ${KLOTSKI_CORE_SRC})
target_compile_options(klotski_core PRIVATE -fno-rtti -fno-exceptions) # option for `-fvisibility=hidden`
target_include_directories(klotski_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(klotski_core PRIVATE absl::flat_hash_map)
target_link_libraries(klotski_core PRIVATE absl::flat_hash_map phmap)
add_library(klotski::core ALIAS klotski_core)
# TODO: just for dev testing

162
src/core/fast_cal/internal/demo.cc

@ -4,7 +4,15 @@
#include <queue>
#include <absl/container/flat_hash_map.h>
//#include <absl/container/flat_hash_map.h>
//#include <absl/hash/hash.h>
//#define PHMAP_USE_ABSL_HASH
//#include <robin_hood.h>
//#include <ankerl/unordered_dense.h>
//#include <tsl/robin_map.h>
#include <parallel_hashmap/phmap.h>
#include "mover/mover.h"
#include "group/group.h"
@ -23,46 +31,91 @@ struct data_t {
// TODO: try wrapper as custom `std::queue`
template <typename T>
class MyQueue {
public:
explicit MyQueue(size_t reserve) {
// vec_.reserve(reserve);
vec_.resize(reserve);
}
void emplace_back(T item) {
// vec_.emplace_back(item);
vec_[iter_] = item;
++iter_;
}
T front() {
return vec_[offset_];
}
void pop() {
++offset_;
}
bool empty() {
return offset_ == iter_;
}
private:
size_t iter_ {0};
size_t offset_ {0};
std::vector<T> vec_ {};
};
class FCDemo {
public:
explicit FCDemo(RawCode raw_code) {
explicit FCDemo(RawCode raw_code) : codes_(GroupUnion::from_raw_code(raw_code).max_group_size()) {
auto reserve = GroupUnion::from_raw_code(raw_code).max_group_size();
codes_.reserve(reserve);
// codes_.reserve(reserve);
cases_.reserve(reserve);
codes_.emplace_back(raw_code);
codes_.emplace_back(raw_code.unwrap());
cases_.emplace(raw_code, data_t {0, 0}); // without mask
}
RawCode DoCal() {
// bool stop_flag = false;
uint64_t result = 0;
auto core = MaskMover([this, &result](uint64_t code, uint64_t mask) {
if (const auto match = cases_.find(code); match != cases_.end()) {
match->second.mask |= mask; // update mask
// match.value().mask |= mask; // update mask
return;
}
cases_.emplace(code, data_t {
.mask = mask,
.back = codes_[offset_].unwrap(),
.back = codes_.front(),
// .back = codes_[offset_].unwrap(),
});
codes_.emplace_back(RawCode::unsafe_create(code));
codes_.emplace_back(code);
if (((code >> 39) & 0b111) == 0b100) {
// stop_flag = true;
result = code;
}
});
while (offset_ != codes_.size()) {
auto curr = codes_[offset_].unwrap();
while (!codes_.empty()) {
auto curr = codes_.front();
core.next_cases(curr, cases_.find(curr)->second.mask);
++offset_;
codes_.pop();
if (result != 0) {
break;
return RawCode::unsafe_create(result);
}
}
return RawCode::unsafe_create(0);
// while (offset_ != codes_.size()) {
// auto curr = codes_[offset_].unwrap();
// core.next_cases(curr, cases_.find(curr)->second.mask);
// ++offset_;
//
// if (result != 0) {
// break;
// }
// }
// std::vector<RawCode> path;
// auto code = result;
// while (true) {
@ -78,89 +131,20 @@ public:
// }
// std::cout << path.size() << std::endl;
return codes_[offset_];
// return codes_[offset_];
}
private:
uint64_t offset_ {0};
std::vector<RawCode> codes_;
absl::flat_hash_map<uint64_t, data_t> cases_; // <code, mask>
// uint64_t offset_ {0};
MyQueue<uint64_t> codes_;
// absl::flat_hash_map<uint64_t, data_t> cases_; // <code, mask>
// robin_hood::unordered_map<uint64_t, data_t> cases_;
// ankerl::unordered_dense::map<uint64_t, data_t> cases_;
// tsl::robin_map<uint64_t, data_t> cases_;
phmap::flat_hash_map<uint64_t, data_t> cases_;
};
RawCode FastCal_demo(RawCode raw_code) {
FCDemo fc {raw_code};
return fc.DoCal();
// std::queue<RawCode> cache;
std::vector<RawCode> codes;
absl::flat_hash_map<uint64_t, data_t> cases; // <code, mask>
auto reserve = GroupUnion::from_raw_code(raw_code).max_group_size();
codes.reserve(reserve);
cases.reserve(reserve);
uint64_t offset = 0;
bool stop_flag = false;
auto core = MaskMover([&codes, &cases, &offset, &stop_flag](uint64_t code, uint64_t mask) {
if (const auto match = cases.find(code); match != cases.end()) {
match->second.mask |= mask; // update mask
return;
}
cases.emplace(code, data_t {
.mask = mask,
.back = codes[offset].unwrap(),
// .back = cache.front().unwrap(),
});
codes.emplace_back(RawCode::unsafe_create(code));
// cache.emplace(RawCode::unsafe_create(code));
if (((code >> 39) & 0b111) == 0b100) {
stop_flag = true;
}
});
codes.emplace_back(raw_code);
// cache.emplace(raw_code);
cases.emplace(raw_code, data_t {0, 0}); // without mask
while (offset != codes.size()) {
auto curr = codes[offset].unwrap();
core.next_cases(curr, cases.find(curr)->second.mask);
++offset;
if (stop_flag) {
break;
}
}
// while (!cache.empty()) {
// if (((cache.front().unwrap() >> 39) & 0b111) == 0b100) {
// break;
// }
// uint64_t curr = cache.front().unwrap();
// core.next_cases(curr, cases.find(curr)->second.mask);
// cache.pop();
// if (stop_flag) {
// break;
// }
// }
// std::vector<RawCode> path;
// auto code = cache.front().unwrap();
// while (true) {
// if (code == 0) {
// break;
// }
// path.emplace_back(RawCode::unsafe_create(code));
// code = cases.find(code)->second.back;
// }
// std::reverse(path.begin(), path.end());
// for (auto step : path) {
// std::cout << step << std::endl;
// }
// std::cout << path.size() << std::endl;
return codes[offset];
// return cache.front();
}

Loading…
Cancel
Save