From bd1bf5a4fa5464dd6a39ca8c6512afaadc52e9d6 Mon Sep 17 00:00:00 2001 From: QifanWang Date: Wed, 30 Nov 2022 21:27:46 +0800 Subject: [PATCH] finish hw06 --- main.cpp | 92 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 27 deletions(-) diff --git a/main.cpp b/main.cpp index a1d2625..c6b3573 100644 --- a/main.cpp +++ b/main.cpp @@ -5,15 +5,22 @@ #include #include #include "ticktock.h" - +#include +#include +#include +#include // TODO: 并行化所有这些 for 循环 template std::vector fill(std::vector &arr, Func const &func) { TICK(fill); - for (size_t i = 0; i < arr.size(); i++) { - arr[i] = func(i); - } + tbb::parallel_for(tbb::blocked_range(0, arr.size()), + [&func, &arr](const tbb::blocked_range& r) { + for (auto i = r.begin(); i != r.end(); i++) + { + arr[i] = func(i); + } + }); TOCK(fill); return arr; } @@ -21,9 +28,13 @@ std::vector fill(std::vector &arr, Func const &func) { template void saxpy(T a, std::vector &x, std::vector const &y) { TICK(saxpy); - for (size_t i = 0; i < x.size(); i++) { - x[i] = a * x[i] + y[i]; - } + tbb::parallel_for(tbb::blocked_range(0, x.size()), + [a, &x, &y](const tbb::blocked_range& r) { + for (auto i = r.begin(); i != r.end(); i++) + { + x[i] = a * x[i] + y[i]; + } + }); TOCK(saxpy); } @@ -31,9 +42,15 @@ template T sqrtdot(std::vector const &x, std::vector const &y) { TICK(sqrtdot); T ret = 0; - for (size_t i = 0; i < std::min(x.size(), y.size()); i++) { - ret += x[i] * y[i]; - } + ret = tbb::parallel_reduce(tbb::blocked_range(0, std::min(x.size(), y.size())), + T{}, + [&x, &y](const tbb::blocked_range& r, T local_val) { + for (size_t i = r.begin(); i != r.end(); i++) + { + local_val += x[i] * y[i]; + } + return local_val; + }, std::plus{}); ret = std::sqrt(ret); TOCK(sqrtdot); return ret; @@ -42,11 +59,15 @@ T sqrtdot(std::vector const &x, std::vector const &y) { template T minvalue(std::vector const &x) { TICK(minvalue); - T ret = x[0]; - for (size_t i = 1; i < x.size(); i++) { - if (x[i] < ret) - ret = x[i]; - } + T ret = tbb::parallel_reduce(tbb::blocked_range(1, x.size()), + x[0], + [&x](const tbb::blocked_range& r, T local_val) { + for (size_t i = r.begin(); i != r.end(); ++i) + if (x[i] < local_val) + local_val = x[i]; + return local_val; + }, + [](T x, T y) { return std::min(x, y);}); TOCK(minvalue); return ret; } @@ -55,14 +76,24 @@ template std::vector magicfilter(std::vector const &x, std::vector const &y) { TICK(magicfilter); std::vector res; - for (size_t i = 0; i < std::min(x.size(), y.size()); i++) { - if (x[i] > y[i]) { - res.push_back(x[i]); - } else if (y[i] > x[i] && y[i] > 0.5f) { - res.push_back(y[i]); - res.push_back(x[i] * y[i]); - } - } + size_t MIN_LEN = std::min(x.size(), y.size()); + res.reserve( MIN_LEN * 2 / 3); + std::mutex mut; + + tbb::parallel_for(tbb::blocked_range(0, MIN_LEN), + [&res, &mut, &x, &y](const tbb::blocked_range& r) { + std::vector local_vec; + local_vec.reserve(r.size()); + for (auto i = r.begin(); i != r.end(); i++) + if (x[i] > y[i]) { + local_vec.push_back(x[i]); + } else if (y[i] > x[i] && y[i] > 0.5f) { + local_vec.push_back(y[i]); + local_vec.push_back(x[i] * y[i]); + } + std::lock_guard lck(mut); + std::copy(local_vec.begin(), local_vec.end(), std::back_inserter(res)); + }); TOCK(magicfilter); return res; } @@ -71,10 +102,17 @@ template T scanner(std::vector &x) { TICK(scanner); T ret = 0; - for (size_t i = 0; i < x.size(); i++) { - ret += x[i]; - x[i] = ret; - } + ret = tbb::parallel_scan(tbb::blocked_range(0, x.size()), + T{}, + [&x](const tbb::blocked_range& r, T local_res, bool is_final) { + for (size_t i = r.begin(); i != r.end(); i++) + { + local_res += x[i]; + if (is_final) + x[i] = local_res; + } + return local_res; + }, std::plus{}); TOCK(scanner); return ret; }