diff --git a/aoc5.cpp b/aoc5.cpp index 3b21bc3..a275516 100644 --- a/aoc5.cpp +++ b/aoc5.cpp @@ -9,12 +9,19 @@ #include #include #include +#include #include -typedef uint32_t Numero; +#define NOMINMAX +#include + +#define NUM_THREADS 10 + +typedef uint64_t Numero; struct MapEntry { Numero src_start; + Numero src_end; Numero dest_start; Numero size; }; @@ -51,38 +58,52 @@ int main() { std::istringstream iss(line); MapEntry ent; iss >> ent.dest_start >> ent.src_start >> ent.size; + ent.src_end = ent.src_start + ent.size; maps[map_idx].push_back(ent); } auto start_time = std::chrono::system_clock::now(); + for (map_idx = 0; map_idx < 7; ++map_idx) { + std::sort(maps[map_idx].begin(), maps[map_idx].end(), [](MapEntry& a, MapEntry& b) { + return a.src_start < b.src_start; + }); + } + + int num_ranges = seeds.size() / 2; - std::vector min_locs; - min_locs.resize(num_ranges); - std::atomic_int progress[32]; + Numero min_locs[NUM_THREADS]; + std::atomic_int progress[NUM_THREADS]; - std::thread progress_thread([num_ranges, &progress]() { + bool finished = false; + std::atomic_int current_range; + current_range.store(0); + + std::thread progress_thread([&progress, &finished, &min_locs, num_ranges, ¤t_range]() { + + HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE); + COORD pos = { 0, 0 }; while (true) { - bool finished = true; - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); - for (int i = 0; i < num_ranges; ++i) { + SetConsoleCursorPosition(output, pos); + + printf("RANGE %d/%d\n", current_range.load() + 1, num_ranges); + + for (int i = 0; i < NUM_THREADS; ++i) { int p = progress[i].load(); - if (p != 100) - finished = false; - char pb[] = " "; for (int c = 0; c < p; ++c) pb[c] = '#'; - printf("%6d%% [%s]\n", p, pb); + printf("Thread %-2d %3d%% [%s]\n", i + 1, p, pb); } printf("\n\n"); @@ -91,68 +112,128 @@ int main() { break; } - - }); //progress_thread.detach(); - omp_set_num_threads(8); + omp_set_num_threads(NUM_THREADS); + + //Numero thread_start[8]; + Numero thread_ranges[NUM_THREADS + 1]; + + Numero min_loc_total = UINT64_MAX; + -#pragma omp parallel for for (int r = 0; r < num_ranges; r++) { - Numero min_loc = UINT32_MAX; Numero start = seeds[r * 2]; Numero end = start + seeds[r * 2 + 1]; - Numero skip = 0; - for (Numero seed = start; seed < end; seed += std::max(1U, skip)) { - Numero find_what = seed; + Numero seed_count = end - start; + Numero seeds_per_thread = seed_count / NUM_THREADS; + //thread_ranges[0] = start; + for (int i = 0; i < NUM_THREADS; ++i) { + thread_ranges[i] = start + i * seeds_per_thread; + } + thread_ranges[NUM_THREADS] = end; - skip = end - start; + current_range.store(r); + +#pragma omp parallel for + for (int t = 0; t < NUM_THREADS; ++t) { + Numero min_loc = UINT64_MAX; + Numero t_start = thread_ranges[t]; + Numero t_end = thread_ranges[t + 1]; + + progress[t] = 0; + + for (Numero seed = t_start; seed < t_end; seed++) { + Numero find_what = seed; + + + for (int i = 0; i < 7; ++i) { + const auto& map = maps[i]; + + int range_start = 0; + int range_end = map.size() - 1; + + while (range_start <= range_end) { + int range_idx = range_start + (range_end - range_start) / 2; + + const auto& range = map[range_idx]; + + if (find_what < range.src_start) { + range_end = range_idx - 1; + } + else if (find_what >= range.src_end) { + range_start = range_idx + 1; + } + else { + find_what = find_what - range.src_start + range.dest_start; + break; + } + + + //if (find_what < range.src_start) { + // range_end = range_idx; + // if (range_end - range_start < 2) + // break; + // continue; + //} + //else if (range.src_start + range.size <= find_what) { + // range_start = range_idx; + // if (range_end - range_start < 2) + // break; + // continue; + //} + //else { + // find_what = find_what - range.src_start + range.dest_start; + // break; + //} - for (int i = 0; i < 7; ++i) { - const auto& map = maps[i]; - for (const auto& range : map) { - if (range.src_start <= find_what && (range.src_start + range.size) > find_what) { - find_what = find_what - range.src_start + range.dest_start; - skip = std::min(skip, (range.src_start + range.size) - find_what); - - //printf("-> %lu\n", find_what); - break; } + + + + //for (const auto& range : map) { + // if (range.src_start <= find_what && (range.src_start + range.size) > find_what) { + // find_what = find_what - range.src_start + range.dest_start; + // //skip = std::min(skip, (range.src_start + range.size) - find_what); + // break; + // } + //} } - skip = 0; + min_loc = std::min(min_loc, find_what); + if (seed % 1000000 == 0) + progress[t] = (float)(seed - t_start) / (float)(t_end - t_start) * 100.0f; + //printf("r %d/%d seed %llu (%.2f%%) min_loc %llu\n", r + 1, num_ranges, seed, (float)(seed - start) / (float)(end - start) * 100.0f, min_loc); + + //seed += skip; } - min_loc = std::min(min_loc, find_what); - if (seed % 1000000 == 0) - progress[r] = (float)(seed - start) / (float)(end - start) * 100.0f; - //printf("r %d/%d seed %llu (%.2f%%) min_loc %llu\n", r + 1, num_ranges, seed, (float)(seed - start) / (float)(end - start) * 100.0f, min_loc); + progress[t] = 100; + min_locs[t] = min_loc; + - //seed += skip; } - progress[r] = 100; - min_locs[r] = min_loc; + for (int i = 0; i < NUM_THREADS; ++i) { + //printf("vysledek thread %d: %llu\n", i, min_locs[i]); + min_loc_total = std::min(min_loc_total, min_locs[i]); + } + //printf("=======\mezivysledek: %llu\n", min_loc_total); } auto end_time = std::chrono::system_clock::now(); + finished = true; progress_thread.join(); - Numero min_loc = UINT32_MAX; - for (int i = 0; i < num_ranges; ++i) { - printf("vysledek range %d: %u\n", i, min_locs[i]); - min_loc = std::min(min_loc, min_locs[i]); - } - - printf("=======\nvysledek: %u\n", min_loc); + printf("=======\nvysledek: %llu\n", min_loc_total); auto time_total = end_time - start_time; printf("time total: %lld s\n", std::chrono::duration_cast(time_total).count()); diff --git a/aoc5.vcxproj b/aoc5.vcxproj index 3550508..8e0f046 100644 --- a/aoc5.vcxproj +++ b/aoc5.vcxproj @@ -105,6 +105,7 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true true + stdcpp17 Console @@ -120,6 +121,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true true + stdcpp17 Console