华容道高性能计算引擎
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

471 lines
13 KiB

#include <iostream>
#include <benchmark/benchmark.h>
// #define private public
#include "group/group.h"
#include <ranges/ranges.h>
#include "../../../third_party/thread-pool/include/BS_thread_pool.hpp"
#include "all_cases/all_cases.h"
// #undef private
using klotski::cases::AllCases;
using klotski::group::CaseInfo;
using klotski::group::Group;
using klotski::group::GroupCases;
using klotski::group::GroupUnion;
using klotski::codec::RawCode;
using klotski::codec::CommonCode;
using klotski::group::TYPE_ID_LIMIT;
/// Build all valid CommonCodes.
static std::vector<uint64_t> all_common_codes() {
std::vector<uint64_t> codes;
for (uint64_t head = 0; head < 16; ++head) {
for (const auto range : AllCases::instance().fetch().ranges(head)) {
codes.emplace_back(head << 32 | range);
}
}
std::cout << "do cal complete" << std::endl;
return codes;
}
std::vector<klotski::codec::CommonCode> common_code_samples(uint64_t num) {
static auto codes = all_common_codes();
uint64_t part_size = codes.size() / num;
// uint64_t offset = 0;
uint64_t offset = part_size / 2;
std::vector<klotski::codec::CommonCode> result;
for (uint64_t i = 0; i < num; ++i) {
uint64_t index = i * part_size + offset;
// // std::cout << "index = " << index << std::endl;
// uint64_t kk[] {343, 666, 114514, 35324, 123454, 76453, 93411};
// uint64_t index = kk[i % 7];
result.emplace_back(klotski::codec::CommonCode::unsafe_create(codes[index]));
}
return result;
}
std::vector<klotski::codec::RawCode> raw_code_samples(uint64_t num) {
auto codes = common_code_samples(num);
std::vector<klotski::codec::RawCode> raw_codes;
raw_codes.reserve(codes.size());
for (auto code : codes) {
raw_codes.emplace_back(code.to_raw_code());
}
return raw_codes;
}
static void CommonCodeToTypeId(benchmark::State &state) {
auto samples = common_code_samples(state.range(0));
for (auto _ : state) {
for (auto code : samples) {
volatile auto ret = GroupUnion::type_id(code);
}
}
state.SetItemsProcessed(state.iterations() * state.range(0));
}
static void RawCodeToTypeId(benchmark::State &state) {
auto samples = raw_code_samples(state.range(0));
for (auto code : samples) {
if (klotski::codec::RawCode::check(code.code_) == false) {
std::cout << "error" << std::endl;
}
}
for (auto _ : state) {
for (auto code : samples) {
volatile auto ret = GroupUnion::type_id(code);
}
}
state.SetItemsProcessed(state.iterations() * state.range(0));
}
static void GroupExtend(benchmark::State &state) {
// auto src = klotski::codec::RawCode::from_common_code(0x1A9BF0C00).value();
// constexpr auto group = Group::unsafe_create(169, 0, Group::Toward::C); // Horizontal (5.33ms)
// constexpr auto group = Group::unsafe_create(5, 0, Group::Toward::A); // Full (8.27ms)
// constexpr auto group = Group::create(182, 0, Group::Toward::A).value(); // Vertical
// const auto group = Group::create(186, 0, Group::Toward::A).value();
// std::cout << (int)group.mirror_type() << std::endl;
// std::vector<Group> groups;
// groups.reserve(25422);
// for (int type_id = 0; type_id < 203; ++type_id) {
// for (auto group : GroupUnion::unsafe_create(type_id).groups()) {
// groups.emplace_back(group);
// }
// }
for (auto _ : state) {
for (int type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
for (auto group : GroupUnion::unsafe_create(type_id).groups()) {
if (group.mirror_type() == Group::MirrorType::Full) {
// if (group.mirror_type() == Group::MirrorType::Horizontal) {
// if (group.mirror_type() == Group::MirrorType::Centro) {
// if (group.mirror_type() == Group::MirrorType::Vertical) {
// if (group.mirror_type() == Group::MirrorType::Ordinary) {
// std::println("{} ({})", group.to_string(), group.size());
volatile auto kk = group.cases();
}
}
}
// constexpr auto group = Group::unsafe_create(89, 0, Group::Toward::A);
// constexpr auto group = Group::unsafe_create(51, 0, Group::Toward::A);
// constexpr auto group = Group::unsafe_create(98, 0, Group::Toward::A);
// volatile auto kk = group.cases();
// for (auto group : groups) {
// volatile auto tmp = group.cases();
// }
// volatile auto tmp = group.cases();
// volatile auto ret = klotski::group::Group_extend(src, 0);
// std::cout << ret.size() << std::endl;
}
// state.SetItemsProcessed(state.iterations());
}
// static void FilterFromAllCases(benchmark::State &state) {
//
// klotski::cases::AllCases::instance().build();
//
// for (auto _ : state) {
// for (uint64_t head = 0; head < 16; ++head) {
//
// for (const auto range : AllCases::instance().fetch()[head]) {
// uint64_t common_code = head << 32 | range;
//
// volatile auto ret = klotski::cases::common_code_to_type_id(common_code);
//
// }
//
// }
// }
//
// }
static std::vector<std::tuple<int, int, int>> target_nums() {
std::vector<std::tuple<int, int, int>> results;
for (int n = 0; n <= 7; ++n) {
for (int n_2x1 = 0; n_2x1 <= n; ++n_2x1) {
for (int n_1x1 = 0; n_1x1 <= (14 - n * 2); ++n_1x1) {
results.emplace_back(n, n_2x1, n_1x1);
}
}
}
results.resize(203);
return results;
}
static void SpawnRanges(benchmark::State &state) {
auto nums = target_nums();
for (auto _ : state) {
klotski::cases::Ranges kk {};
kk.reserve(7311921);
for (auto [n, n_2x1, n_1x1] : nums) {
kk.spawn(n, n_2x1, n_1x1);
}
}
}
static void OriginBasicRanges(benchmark::State &state) {
BS::thread_pool pool {4};
for (auto _ : state) {
auto &kk = klotski::cases::BasicRanges::instance();
// kk.build_ranges(kk.get_ranges());
kk.available_ = false;
// kk.build();
// kk.build_async([](auto func) {func();}, [](){});
kk.build_async([&pool](auto func) {
pool.submit_task(func);
}, [] {});
pool.wait();
}
}
static void OriginAllCases(benchmark::State &state) {
klotski::cases::BasicRanges::instance().build();
// klotski::cases::get_reversed();
// BS::thread_pool pool {4};
for (auto _ : state) {
auto &pp = klotski::cases::AllCases::instance();
pp.available_ = false;
pp.build();
// pp.build_parallel_async([](auto func) {func();}, []() {
// // std::cout << "hello" << std::endl;
// });
// pp.build_parallel_async([&pool](auto func) {
// pool.submit_task(func);
// }, [] {});
//
// pool.wait();
}
}
static void RangesDerive(benchmark::State &state) {
auto &basic_ranges = klotski::cases::BasicRanges::instance().fetch();
// klotski::cases::Ranges results;
// results.reserve(klotski::cases::ALL_CASES_NUM_);
auto group_union = klotski::group::GroupUnion::unsafe_create(169);
std::vector<klotski::group::GroupUnion> unions;
unions.reserve(klotski::group::TYPE_ID_LIMIT);
for (int type_id = 0; type_id < klotski::group::TYPE_ID_LIMIT; ++type_id) {
unions.emplace_back(klotski::group::GroupUnion::create(type_id).value());
}
for (auto _ : state) {
// results.clear();
// results.reserve(klotski::cases::ALL_CASES_NUM[5]);
// volatile auto tmp = group_union.cases();
for (auto g_union : unions) {
volatile auto tmp = g_union.cases();
}
}
// std::cout << results.size() << " vs " << klotski::cases::ALL_CASES_NUM[5] << std::endl;
}
static void SpawnGroups(benchmark::State &state) {
volatile int type_id = 169;
auto gu = GroupUnion::unsafe_create(type_id);
for (auto _ : state) {
// volatile auto kk = gu.groups();
for (auto pattern_id = 0; pattern_id < gu.pattern_num(); ++pattern_id) {
volatile auto kk = gu.groups(pattern_id);
}
}
}
static void GroupFromRawCode(benchmark::State &state) {
auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
for (auto _ : state) {
volatile auto g = Group::from_raw_code(code);
}
}
static void IsVerticalMirror(benchmark::State &state) {
volatile int type_id = 169;
const auto groups = GroupUnion::unsafe_create(type_id).groups();
for (auto _ : state) {
for (auto group : groups) {
volatile auto kk = group.is_vertical_mirror();
}
}
}
static void IsHorizontalMirror(benchmark::State &state) {
volatile int type_id = 169;
const auto groups = GroupUnion::unsafe_create(type_id).groups();
for (auto _ : state) {
for (auto group : groups) {
volatile auto kk = group.is_horizontal_mirror();
}
}
}
static void ToVerticalMirror(benchmark::State &state) {
volatile int type_id = 169;
const auto groups = GroupUnion::unsafe_create(type_id).groups();
for (auto _ : state) {
for (auto group : groups) {
volatile auto kk = group.to_vertical_mirror();
}
}
}
static void ToHorizontalMirror(benchmark::State &state) {
volatile int type_id = 169;
const auto groups = GroupUnion::unsafe_create(type_id).groups();
for (auto _ : state) {
for (auto group : groups) {
volatile auto kk = group.to_horizontal_mirror();
}
}
}
static void FastObtainCode(benchmark::State &state) {
GroupCases::build();
// std::vector<CaseInfo> infos;
// for (auto code : common_code_samples(64)) {
// infos.emplace_back(GroupCases::tiny_obtain_info(code));
// }
// infos.emplace_back(CaseInfo::unsafe_create())
const auto group = Group::unsafe_create(169, 0, Group::Toward::C);
// const klotski::cases::RangesUnion data = group.cases();
//
// std::array<size_t, 16> sizes {};
// size_t offset = 0;
// for (int i = 0; i < 16; ++i) {
// sizes[i] = offset;
// offset += data.ranges(i).size();
// }
std::vector infos {
CaseInfo::unsafe_create(group, 2631),
CaseInfo::unsafe_create(group, 4203),
CaseInfo::unsafe_create(group, 4504),
CaseInfo::unsafe_create(group, 5178),
CaseInfo::unsafe_create(group, 5411),
CaseInfo::unsafe_create(group, 7208),
CaseInfo::unsafe_create(group, 8385),
CaseInfo::unsafe_create(group, 9821),
CaseInfo::unsafe_create(group, 14220),
CaseInfo::unsafe_create(group, 16159),
CaseInfo::unsafe_create(group, 16224),
CaseInfo::unsafe_create(group, 18027),
CaseInfo::unsafe_create(group, 20271),
CaseInfo::unsafe_create(group, 20980),
CaseInfo::unsafe_create(group, 21130),
CaseInfo::unsafe_create(group, 22794),
};
for (auto _ : state) {
// for (auto info : infos) {
// volatile auto kk = GroupCases::fast_obtain_code(info);
// }
// volatile auto kk = GroupCases::fast_obtain_code(info);
for (auto info : infos) {
/// about 35ns
// auto &cases = data;
// uint64_t head = 0;
// auto case_id = info.case_id();
// for (;;) {
// if (case_id >= cases.ranges(head).size()) {
// case_id -= cases.ranges(head).size();
// ++head;
// } else {
// break;
// }
// }
// auto range = cases.ranges(head)[case_id];
// volatile auto kk = CommonCode::unsafe_create(head << 32 | range);
/// about 117ns
// uint64_t head = std::upper_bound(sizes.begin(), sizes.end(), info.case_id()) - sizes.begin() - 1;
// uint32_t range = data[head][info.case_id() - sizes[head]];
// volatile auto kk = CommonCode::unsafe_create(head << 32 | range);
volatile auto kk = GroupCases::fast_obtain_code(info);
}
}
}
// BENCHMARK(CommonCodeToTypeId)->Arg(8)->Arg(64)->Arg(256);
// BENCHMARK(RawCodeToTypeId)->Arg(8)->Arg(64)->Arg(256);
// BENCHMARK(GroupExtend)->Unit(benchmark::kMillisecond);
// BENCHMARK(GroupExtend)->Unit(benchmark::kMicrosecond);
// BENCHMARK(FilterFromAllCases)->Unit(benchmark::kMillisecond);
// BENCHMARK(SpawnRanges)->Unit(benchmark::kMillisecond);
// BENCHMARK(OriginBasicRanges)->Unit(benchmark::kMillisecond);
// BENCHMARK(OriginAllCases)->Unit(benchmark::kMillisecond);
// BENCHMARK(RangesDerive)->Unit(benchmark::kMillisecond);
// BENCHMARK(SpawnGroups);
// BENCHMARK(GroupFromRawCode)->Unit(benchmark::kMillisecond);
BENCHMARK(FastObtainCode);
// BENCHMARK(IsVerticalMirror);
// BENCHMARK(IsHorizontalMirror);
// BENCHMARK(ToVerticalMirror);
// BENCHMARK(ToHorizontalMirror);
BENCHMARK_MAIN();