uz to seru
This commit is contained in:
parent
e510dc9839
commit
f305ad94d1
171
aoc5.cpp
171
aoc5.cpp
@ -9,12 +9,19 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <algorithm>
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
|
|
||||||
typedef uint32_t Numero;
|
#define NOMINMAX
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define NUM_THREADS 10
|
||||||
|
|
||||||
|
typedef uint64_t Numero;
|
||||||
|
|
||||||
struct MapEntry {
|
struct MapEntry {
|
||||||
Numero src_start;
|
Numero src_start;
|
||||||
|
Numero src_end;
|
||||||
Numero dest_start;
|
Numero dest_start;
|
||||||
Numero size;
|
Numero size;
|
||||||
};
|
};
|
||||||
@ -51,38 +58,52 @@ int main() {
|
|||||||
std::istringstream iss(line);
|
std::istringstream iss(line);
|
||||||
MapEntry ent;
|
MapEntry ent;
|
||||||
iss >> ent.dest_start >> ent.src_start >> ent.size;
|
iss >> ent.dest_start >> ent.src_start >> ent.size;
|
||||||
|
ent.src_end = ent.src_start + ent.size;
|
||||||
maps[map_idx].push_back(ent);
|
maps[map_idx].push_back(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto start_time = std::chrono::system_clock::now();
|
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;
|
int num_ranges = seeds.size() / 2;
|
||||||
|
|
||||||
std::vector<Numero> min_locs;
|
Numero min_locs[NUM_THREADS];
|
||||||
min_locs.resize(num_ranges);
|
std::atomic_int progress[NUM_THREADS];
|
||||||
std::atomic_int progress[32];
|
|
||||||
|
|
||||||
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) {
|
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();
|
int p = progress[i].load();
|
||||||
|
|
||||||
if (p != 100)
|
|
||||||
finished = false;
|
|
||||||
|
|
||||||
char pb[] = " ";
|
char pb[] = " ";
|
||||||
|
|
||||||
for (int c = 0; c < p; ++c)
|
for (int c = 0; c < p; ++c)
|
||||||
pb[c] = '#';
|
pb[c] = '#';
|
||||||
|
|
||||||
|
|
||||||
printf("%6d%% [%s]\n", p, pb);
|
printf("Thread %-2d %3d%% [%s]\n", i + 1, p, pb);
|
||||||
|
|
||||||
}
|
}
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
@ -91,68 +112,128 @@ int main() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//progress_thread.detach();
|
//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++) {
|
for (int r = 0; r < num_ranges; r++) {
|
||||||
Numero min_loc = UINT32_MAX;
|
|
||||||
|
|
||||||
Numero start = seeds[r * 2];
|
Numero start = seeds[r * 2];
|
||||||
Numero end = start + seeds[r * 2 + 1];
|
Numero end = start + seeds[r * 2 + 1];
|
||||||
|
|
||||||
Numero skip = 0;
|
Numero seed_count = end - start;
|
||||||
for (Numero seed = start; seed < end; seed += std::max(1U, skip)) {
|
Numero seeds_per_thread = seed_count / NUM_THREADS;
|
||||||
Numero find_what = seed;
|
//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);
|
progress[t] = 100;
|
||||||
if (seed % 1000000 == 0)
|
min_locs[t] = min_loc;
|
||||||
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);
|
|
||||||
|
|
||||||
//seed += skip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
progress[r] = 100;
|
for (int i = 0; i < NUM_THREADS; ++i) {
|
||||||
min_locs[r] = min_loc;
|
//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();
|
auto end_time = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
finished = true;
|
||||||
progress_thread.join();
|
progress_thread.join();
|
||||||
|
|
||||||
Numero min_loc = UINT32_MAX;
|
printf("=======\nvysledek: %llu\n", min_loc_total);
|
||||||
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);
|
|
||||||
|
|
||||||
auto time_total = end_time - start_time;
|
auto time_total = end_time - start_time;
|
||||||
printf("time total: %lld s\n", std::chrono::duration_cast<std::chrono::seconds>(time_total).count());
|
printf("time total: %lld s\n", std::chrono::duration_cast<std::chrono::seconds>(time_total).count());
|
||||||
|
|||||||
@ -105,6 +105,7 @@
|
|||||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<OpenMPSupport>true</OpenMPSupport>
|
<OpenMPSupport>true</OpenMPSupport>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -120,6 +121,7 @@
|
|||||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<OpenMPSupport>true</OpenMPSupport>
|
<OpenMPSupport>true</OpenMPSupport>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user