Browse Source

update: enhance benchmark module

legacy
Dnomd343 2 years ago
parent
commit
f0a8d401f3
  1. 91
      src/klotski_core/benchmark/benchmark.cc
  2. 21
      src/klotski_core/benchmark/benchmark.h
  3. 36
      src/klotski_core/benchmark/chore.cc
  4. 63
      src/klotski_core/ffi/tmain.cc

91
src/klotski_core/benchmark/benchmark.cc

@ -1,8 +1,23 @@
#include "common.h"
#include "benchmark.h" #include "benchmark.h"
#include "all_cases.h" #include "all_cases.h"
using klotski::Benchmark; using klotski::Benchmark;
/// ----------------------------- Benchmark Utils -----------------------------
double Benchmark::range_flip(TIME format) noexcept {
uint32_t num = 0;
auto start = clock();
for (uint32_t i = 0; i < 0x1'0000'0000 - 0xF; i += 0xE) {
Common::range_reverse(i);
++num;
}
return time_format(start, format) / (double)num;
}
/// --------------------------- Benchmark AllCases ----------------------------
double Benchmark::basic_ranges(TIME format) noexcept { double Benchmark::basic_ranges(TIME format) noexcept {
if (BasicRanges::status() != BasicRanges::NO_INIT) { if (BasicRanges::status() != BasicRanges::NO_INIT) {
return -1; // data already built -> skip return -1; // data already built -> skip
@ -22,12 +37,82 @@ double Benchmark::all_cases(TIME format) noexcept {
return time_format(start, format); return time_format(start, format);
} }
/// -------------------------- Benchmark Code Check ---------------------------
double Benchmark::raw_code_check(TIME format) noexcept {
if (!data_ready) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&raw_code : all_raw_codes) {
raw_code.valid();
}
return time_format(start, format) / (double)all_raw_codes.size();
}
double Benchmark::short_code_check(TIME format) noexcept {
if (!data_ready) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&short_code : all_short_codes) {
short_code.valid();
}
return time_format(start, format) / (double)all_short_codes.size();
}
double Benchmark::common_code_check(TIME format) noexcept {
if (!data_ready) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&common_code : all_common_codes) {
common_code.valid();
}
return time_format(start, format) / (double)all_common_codes.size();
}
double Benchmark::raw_code_check_random(TIME format) noexcept {
auto random_data = generate_u64_rand(klotski::ALL_CASES_SIZE_SUM);
for (auto &&val : random_data) {
val &= ~((uint64_t)0b1111 << 60); // clear high 4-bits
}
auto start = clock();
for (auto &&raw_code : random_data) {
RawCode::check(raw_code);
}
return time_format(start, format) / (double)random_data.size();
}
double Benchmark::short_code_check_random(TIME format) noexcept {
auto random_data = generate_u32_rand(klotski::ALL_CASES_SIZE_SUM);
auto start = clock();
for (auto &&short_code : random_data) {
ShortCode::check(short_code);
}
return time_format(start, format) / (double)random_data.size();
}
double Benchmark::common_code_check_random(TIME format) noexcept {
auto random_data = generate_u64_rand(klotski::ALL_CASES_SIZE_SUM);
for (auto &&val : random_data) {
val &= ~((uint64_t)0xFFFFFFF << 36); // clear high 28-bits
}
auto start = clock();
for (auto &&common_code : random_data) {
CommonCode::check(common_code);
}
return time_format(start, format) / (double)random_data.size();
}
/// -------------------------- Benchmark Code String --------------------------
double Benchmark::short_code_to_string(TIME format) noexcept { double Benchmark::short_code_to_string(TIME format) noexcept {
if (!data_ready) { if (!data_ready) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (const auto &short_code : all_short_codes) { for (auto &&short_code : all_short_codes) {
short_code.to_string(); short_code.to_string();
} }
return time_format(start, format) / (double)all_short_codes.size(); return time_format(start, format) / (double)all_short_codes.size();
@ -49,7 +134,7 @@ double Benchmark::common_code_to_string(TIME format) noexcept {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (const auto &common_code : all_common_codes) { for (auto &&common_code : all_common_codes) {
common_code.to_string(); common_code.to_string();
} }
return time_format(start, format) / (double)all_common_codes.size(); return time_format(start, format) / (double)all_common_codes.size();
@ -66,6 +151,8 @@ double Benchmark::common_code_from_string(TIME format) noexcept {
return time_format(start, format) / (double)all_common_codes_str.size(); return time_format(start, format) / (double)all_common_codes_str.size();
} }
/// ------------------------- Benchmark Code Convert --------------------------
double Benchmark::common_code_to_raw_code(TIME format) noexcept { double Benchmark::common_code_to_raw_code(TIME format) noexcept {
if (!data_ready) { if (!data_ready) {
return -1; // data no ready -> skip return -1; // data no ready -> skip

21
src/klotski_core/benchmark/benchmark.h

@ -34,9 +34,19 @@ namespace klotski {
static void data_preparation() noexcept; static void data_preparation() noexcept;
static double warm_up(uint64_t count) noexcept; static double warm_up(uint64_t count) noexcept;
static double range_flip(TIME format = NS) noexcept;
static double all_cases(TIME format = MS) noexcept; static double all_cases(TIME format = MS) noexcept;
static double basic_ranges(TIME format = MS) noexcept; static double basic_ranges(TIME format = MS) noexcept;
static double raw_code_check(TIME format = NS) noexcept;
static double short_code_check(TIME format = NS) noexcept;
static double common_code_check(TIME format = NS) noexcept;
static double raw_code_check_random(TIME format = NS) noexcept;
static double short_code_check_random(TIME format = NS) noexcept;
static double common_code_check_random(TIME format = NS) noexcept;
static double short_code_to_string(TIME format = NS) noexcept; static double short_code_to_string(TIME format = NS) noexcept;
static double short_code_from_string(TIME format = NS) noexcept; static double short_code_from_string(TIME format = NS) noexcept;
@ -52,14 +62,6 @@ namespace klotski {
static double common_code_to_short_code_fast(TIME format = NS) noexcept; static double common_code_to_short_code_fast(TIME format = NS) noexcept;
static double short_code_to_common_code_fast(TIME format = NS) noexcept; static double short_code_to_common_code_fast(TIME format = NS) noexcept;
// static float codec_common_to_raw(TIME format = US);
// static float codec_raw_to_common(TIME format = US);
// static float codec_common_to_short();
// static float codec_short_to_common();
// static float codec_common_to_short_fast();
// static float codec_short_to_common_fast();
private: private:
static bool data_ready; static bool data_ready;
static std::vector<RawCode> all_raw_codes; static std::vector<RawCode> all_raw_codes;
@ -68,6 +70,9 @@ namespace klotski {
static std::vector<std::string> all_short_codes_str; static std::vector<std::string> all_short_codes_str;
static std::vector<std::string> all_common_codes_str; static std::vector<std::string> all_common_codes_str;
static uint32_t random_seed() noexcept;
static double time_format(clock_t start, TIME format) noexcept; static double time_format(clock_t start, TIME format) noexcept;
static std::vector<uint32_t> generate_u32_rand(uint32_t count) noexcept;
static std::vector<uint64_t> generate_u64_rand(uint32_t count) noexcept;
}; };
} }

36
src/klotski_core/benchmark/chore.cc

@ -1,4 +1,5 @@
#include <thread> #include <chrono>
#include <random>
#include "benchmark.h" #include "benchmark.h"
using klotski::RawCode; using klotski::RawCode;
@ -13,6 +14,12 @@ std::vector<CommonCode> Benchmark::all_common_codes;
std::vector<std::string> Benchmark::all_short_codes_str; std::vector<std::string> Benchmark::all_short_codes_str;
std::vector<std::string> Benchmark::all_common_codes_str; std::vector<std::string> Benchmark::all_common_codes_str;
uint32_t Benchmark::random_seed() noexcept {
using namespace std::chrono;
auto tmp = system_clock::now().time_since_epoch();
return duration_cast<microseconds>(tmp).count();
}
double Benchmark::warm_up(uint64_t count) noexcept { double Benchmark::warm_up(uint64_t count) noexcept {
auto start = clock(); auto start = clock();
volatile uint64_t tmp = 0; volatile uint64_t tmp = 0;
@ -39,6 +46,33 @@ double Benchmark::time_format(clock_t start, TIME format) noexcept {
return time / CLOCKS_PER_SEC; return time / CLOCKS_PER_SEC;
} }
std::vector<uint32_t> Benchmark::generate_u32_rand(uint32_t count) noexcept {
std::vector<uint32_t> result;
result.reserve(count);
auto seed = random_seed();
auto high_bit = (uint32_t)seed << 31;
std::srand(seed);
for (uint32_t i = 0; i < count; ++i) {
auto tmp = high_bit | static_cast<uint32_t>(std::rand());
result.emplace_back(tmp);
high_bit = tmp << 31;
}
return result;
}
std::vector<uint64_t> Benchmark::generate_u64_rand(uint32_t count) noexcept {
std::vector<uint64_t> result;
result.reserve(count);
auto tmp = generate_u32_rand(count * 2);
for (uint32_t i = 0; i < count; ++i) {
result.emplace_back((uint64_t)tmp[i * 2] << 32 | tmp[i * 2 + 1]);
}
return result;
}
void Benchmark::data_preparation() noexcept { void Benchmark::data_preparation() noexcept {
if (Benchmark::data_ready) { if (Benchmark::data_ready) {
return; return;

63
src/klotski_core/ffi/tmain.cc

@ -18,27 +18,54 @@ void tmain() {
// std::cout << "warm up: " << Benchmark::warm_up(1000000) << "us" << std::endl; // std::cout << "warm up: " << Benchmark::warm_up(1000000) << "us" << std::endl;
// std::cout << "basic ranges: " << Benchmark::basic_ranges() << "ms" << std::endl; std::cout << "range flip: " <<
// std::cout << "all cases: " << Benchmark::all_cases() << "ms" << std::endl; Benchmark::range_flip() << "ns" << std::endl;
Benchmark::data_preparation(); std::cout << "basic ranges: " <<
Benchmark::basic_ranges() << "ms" << std::endl;
std::cout << "start benchmark" << std::endl; std::cout << "all cases: " <<
Benchmark::all_cases() << "ms" << std::endl;
// std::cout << Benchmark::short_code_to_string() << "ns" << std::endl; Benchmark::data_preparation();
// std::cout << Benchmark::short_code_from_string() << "ns" << std::endl;
//
// std::cout << Benchmark::common_code_to_string() << "ns" << std::endl;
// std::cout << Benchmark::common_code_from_string() << "ns" << std::endl;
//
// std::cout << Benchmark::common_code_to_raw_code() << "ns" << std::endl;
// std::cout << Benchmark::raw_code_to_common_code() << "ns" << std::endl;
std::cout << Benchmark::common_code_to_short_code() << "ns" << std::endl;
std::cout << Benchmark::short_code_to_common_code() << "ns" << std::endl;
std::cout << Benchmark::common_code_to_short_code_fast() << "ns" << std::endl; std::cout << "raw code check: " <<
std::cout << Benchmark::short_code_to_common_code_fast() << "ns" << std::endl; Benchmark::raw_code_check() << "ns" << std::endl;
std::cout << "short code check: " <<
Benchmark::short_code_check() << "ns" << std::endl;
std::cout << "common code check: " <<
Benchmark::common_code_check() << "ns" << std::endl;
std::cout << "raw code check random: " <<
Benchmark::raw_code_check_random() << "ns" << std::endl;
std::cout << "short code check random: " <<
Benchmark::short_code_check_random() << "ns" << std::endl;
std::cout << "common code check random: " <<
Benchmark::common_code_check_random() << "ns" << std::endl;
std::cout << "short code to string: " <<
Benchmark::short_code_to_string() << "ns" << std::endl;
std::cout << "short code from string: " <<
Benchmark::short_code_from_string() << "ns" << std::endl;
std::cout << "common code to string: " <<
Benchmark::common_code_to_string() << "ns" << std::endl;
std::cout << "common code from string: " <<
Benchmark::common_code_from_string() << "ns" << std::endl;
std::cout << "common code to raw code: " <<
Benchmark::common_code_to_raw_code() << "ns" << std::endl;
std::cout << "raw code to common code: " <<
Benchmark::raw_code_to_common_code() << "ns" << std::endl;
std::cout << "common code to short code: " <<
Benchmark::common_code_to_short_code() << "ns" << std::endl;
std::cout << "short code to common code: " <<
Benchmark::short_code_to_common_code() << "ns" << std::endl;
std::cout << "common code to short code fast: " <<
Benchmark::common_code_to_short_code_fast() << "ns" << std::endl;
std::cout << "short code to common code fast: " <<
Benchmark::short_code_to_common_code_fast() << "ns" << std::endl;
return; return;

Loading…
Cancel
Save