From b42e21532c1acc17b41b54ccf2de0326c1791047 Mon Sep 17 00:00:00 2001 From: TepidmishA Date: Wed, 15 Apr 2026 19:19:56 +0300 Subject: [PATCH 1/6] Sequential hull construction moved to separate method --- .../omp/include/ops_omp.hpp | 4 +++ .../omp/src/ops_omp.cpp | 30 +++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp index 6cd10b047..d01bff48d 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp @@ -24,6 +24,10 @@ class PerepelkinIConvexHullGrahamScanOMP : public BaseTask { static size_t FindPivotParallel(const std::vector> &pts); static void ParallelSort(std::vector> &data, const std::pair &pivot); + + static void HullConstruction(std::vector> &hull, + const std::vector> &pts, + const std::pair &pivot); static bool AngleCmp(const std::pair &a, const std::pair &b, const std::pair &pivot); static double Orientation(const std::pair &p, const std::pair &q, diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp index e2a52998b..4f05d12a1 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp @@ -47,18 +47,7 @@ bool PerepelkinIConvexHullGrahamScanOMP::RunImpl() { // Sequential hull construction std::vector> hull; - hull.reserve(pts.size() + 1); - - hull.push_back(pivot); - hull.push_back(pts[0]); - - for (size_t i = 1; i < pts.size(); i++) { - while (hull.size() >= 2 && Orientation(hull[hull.size() - 2], hull[hull.size() - 1], pts[i]) <= 0) { - hull.pop_back(); - } - - hull.push_back(pts[i]); - } + HullConstruction(hull, pts, pivot); GetOutput() = std::move(hull); return true; @@ -131,6 +120,23 @@ void PerepelkinIConvexHullGrahamScanOMP::ParallelSort(std::vector> &hull, const std::vector> &pts, + const std::pair &pivot) { + hull.reserve(pts.size() + 1); + + hull.push_back(pivot); + hull.push_back(pts[0]); + + for (size_t i = 1; i < pts.size(); i++) { + while (hull.size() >= 2 && Orientation(hull[hull.size() - 2], hull[hull.size() - 1], pts[i]) <= 0) { + hull.pop_back(); + } + + hull.push_back(pts[i]); + } +} + double PerepelkinIConvexHullGrahamScanOMP::Orientation(const std::pair &p, const std::pair &q, const std::pair &r) { From a2253115184d370193f21b1d638df11b3f8f7949 Mon Sep 17 00:00:00 2001 From: TepidmishA Date: Wed, 15 Apr 2026 19:21:28 +0300 Subject: [PATCH 2/6] remove ParallelSort `n < 10000` branch --- .../perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp index 4f05d12a1..6970ae17d 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp @@ -85,11 +85,6 @@ void PerepelkinIConvexHullGrahamScanOMP::ParallelSort(std::vector start(threads + 1); for (int i = 0; i <= threads; i++) { start[i] = static_cast(i * n / threads); From 4f762210364e4c022b3701ceebe5ae32e04d1359 Mon Sep 17 00:00:00 2001 From: TepidmishA Date: Wed, 15 Apr 2026 19:29:48 +0300 Subject: [PATCH 3/6] fix code style --- .../omp/include/ops_omp.hpp | 4 ++-- .../omp/src/ops_omp.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp index d01bff48d..d852d0006 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp @@ -26,8 +26,8 @@ class PerepelkinIConvexHullGrahamScanOMP : public BaseTask { static void ParallelSort(std::vector> &data, const std::pair &pivot); static void HullConstruction(std::vector> &hull, - const std::vector> &pts, - const std::pair &pivot); + const std::vector> &pts, + const std::pair &pivot); static bool AngleCmp(const std::pair &a, const std::pair &b, const std::pair &pivot); static double Orientation(const std::pair &p, const std::pair &q, diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp index 6970ae17d..fbd01c7e7 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp @@ -115,9 +115,9 @@ void PerepelkinIConvexHullGrahamScanOMP::ParallelSort(std::vector> &hull, const std::vector> &pts, - const std::pair &pivot) { +void PerepelkinIConvexHullGrahamScanOMP::HullConstruction(std::vector> &hull, + const std::vector> &pts, + const std::pair &pivot) { hull.reserve(pts.size() + 1); hull.push_back(pivot); From 064758d16b37ba4d409932229e5772598f5f32c9 Mon Sep 17 00:00:00 2001 From: TepidmishA Date: Wed, 15 Apr 2026 20:31:32 +0300 Subject: [PATCH 4/6] change critical section reduction to sequential --- .../omp/src/ops_omp.cpp | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp index fbd01c7e7..7bca9b257 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp @@ -55,25 +55,32 @@ bool PerepelkinIConvexHullGrahamScanOMP::RunImpl() { size_t PerepelkinIConvexHullGrahamScanOMP::FindPivotParallel(const std::vector> &pts) { size_t pivot_idx = 0; + const int threads = ppc::util::GetNumThreads(); + std::vector local_idx(threads, 0); -#pragma omp parallel default(none) shared(pts, pivot_idx) num_threads(ppc::util::GetNumThreads()) +#pragma omp parallel default(none) shared(pts, local_idx) num_threads(threads) { - size_t local_idx = pivot_idx; + int tid = omp_get_thread_num(); + size_t local = 0; #pragma omp for nowait for (size_t i = 1; i < pts.size(); i++) { - if (pts[i].second < pts[local_idx].second || - (pts[i].second == pts[local_idx].second && pts[i].first < pts[local_idx].first)) { - local_idx = i; + if (pts[i].second < pts[local].second || + (pts[i].second == pts[local].second && pts[i].first < pts[local].first)) { + local = i; } } -#pragma omp critical - { - if (pts[local_idx].second < pts[pivot_idx].second || - (pts[local_idx].second == pts[pivot_idx].second && pts[local_idx].first < pts[pivot_idx].first)) { - pivot_idx = local_idx; - } + local_idx[tid] = local; + } + + // Sequential reduction + for (int tid = 0; tid < threads; tid++) { + size_t i = local_idx[tid]; + + if (pts[i].second < pts[pivot_idx].second || + (pts[i].second == pts[pivot_idx].second && pts[i].first < pts[pivot_idx].first)) { + pivot_idx = i; } } From e05791e858f5a123aeb90055e86a8dab180b328a Mon Sep 17 00:00:00 2001 From: TepidmishA Date: Wed, 15 Apr 2026 21:49:20 +0300 Subject: [PATCH 5/6] fix data partitioning --- .../omp/include/ops_omp.hpp | 1 + .../omp/src/ops_omp.cpp | 37 ++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp index d852d0006..30746ef1f 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp @@ -25,6 +25,7 @@ class PerepelkinIConvexHullGrahamScanOMP : public BaseTask { static size_t FindPivotParallel(const std::vector> &pts); static void ParallelSort(std::vector> &data, const std::pair &pivot); + static void DataPartitioning(size_t total_size, const int &threads, std::vector &start); static void HullConstruction(std::vector> &hull, const std::vector> &pts, const std::pair &pivot); diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp index 7bca9b257..3ddfe6d9f 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp @@ -54,8 +54,7 @@ bool PerepelkinIConvexHullGrahamScanOMP::RunImpl() { } size_t PerepelkinIConvexHullGrahamScanOMP::FindPivotParallel(const std::vector> &pts) { - size_t pivot_idx = 0; - const int threads = ppc::util::GetNumThreads(); + const int threads = std::min(ppc::util::GetNumThreads(), static_cast(pts.size())); std::vector local_idx(threads, 0); #pragma omp parallel default(none) shared(pts, local_idx) num_threads(threads) @@ -75,6 +74,8 @@ size_t PerepelkinIConvexHullGrahamScanOMP::FindPivotParallel(const std::vector> &data, const std::pair &pivot) { - size_t n = data.size(); - int threads = ppc::util::GetNumThreads(); + const int threads = std::min(ppc::util::GetNumThreads(), static_cast(data.size())); - std::vector start(threads + 1); - for (int i = 0; i <= threads; i++) { - start[i] = static_cast(i * n / threads); - } + // Partitioning + std::vector start(threads + 1); + DataPartitioning(data.size(), threads, start); -#pragma omp parallel default(none) shared(data, start, pivot) num_threads(ppc::util::GetNumThreads()) + // Parallel local sorting +#pragma omp parallel default(none) shared(data, start, pivot) num_threads(threads) { int tid = omp_get_thread_num(); std::sort(data.begin() + start[tid], data.begin() + start[tid + 1], @@ -106,7 +106,7 @@ void PerepelkinIConvexHullGrahamScanOMP::ParallelSort(std::vector= threads) { continue; @@ -122,6 +122,23 @@ void PerepelkinIConvexHullGrahamScanOMP::ParallelSort(std::vector &start) { + size_t base = total_size / threads; + size_t rem = total_size % threads; + + size_t offset = 0; + + for (int i = 0; i < threads; i++) { + start[i] = offset; + + size_t extra = (i < static_cast(rem)) ? 1 : 0; + offset += base + extra; + } + + start[threads] = total_size; +} + void PerepelkinIConvexHullGrahamScanOMP::HullConstruction(std::vector> &hull, const std::vector> &pts, const std::pair &pivot) { From daefdedffa9903ef8cb9ea034e4afb0ed271ffde Mon Sep 17 00:00:00 2001 From: TepidmishA Date: Thu, 16 Apr 2026 08:23:19 +0300 Subject: [PATCH 6/6] fix code style --- .../omp/include/ops_omp.hpp | 2 +- .../omp/src/ops_omp.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp index 30746ef1f..3933b434c 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/include/ops_omp.hpp @@ -25,7 +25,7 @@ class PerepelkinIConvexHullGrahamScanOMP : public BaseTask { static size_t FindPivotParallel(const std::vector> &pts); static void ParallelSort(std::vector> &data, const std::pair &pivot); - static void DataPartitioning(size_t total_size, const int &threads, std::vector &start); + static void DataPartitioning(size_t total_size, const int &threads, std::vector &start); static void HullConstruction(std::vector> &hull, const std::vector> &pts, const std::pair &pivot); diff --git a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp index 3ddfe6d9f..46ac7d7bf 100644 --- a/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp +++ b/tasks/perepelkin_i_convex_hull_graham_scan/omp/src/ops_omp.cpp @@ -93,7 +93,7 @@ void PerepelkinIConvexHullGrahamScanOMP::ParallelSort(std::vector(data.size())); // Partitioning - std::vector start(threads + 1); + std::vector start(threads + 1); DataPartitioning(data.size(), threads, start); // Parallel local sorting @@ -123,20 +123,20 @@ void PerepelkinIConvexHullGrahamScanOMP::ParallelSort(std::vector &start) { + std::vector &start) { size_t base = total_size / threads; size_t rem = total_size % threads; size_t offset = 0; for (int i = 0; i < threads; i++) { - start[i] = offset; + start[i] = static_cast(offset); - size_t extra = (i < static_cast(rem)) ? 1 : 0; + size_t extra = std::cmp_less(i, rem) ? 1 : 0; offset += base + extra; } - start[threads] = total_size; + start[threads] = static_cast(total_size); } void PerepelkinIConvexHullGrahamScanOMP::HullConstruction(std::vector> &hull,