diff --git a/main.cpp b/main.cpp index a1d2625..26edb2f 100644 --- a/main.cpp +++ b/main.cpp @@ -4,6 +4,10 @@ #include #include #include +#include +#include +#include +#include #include "ticktock.h" // TODO: 并行化所有这些 for 循环 @@ -11,9 +15,12 @@ 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()), + [&](tbb::blocked_range r) { + for (size_t i = r.begin(); i < r.end(); ++i) { + arr[i] = func(i); + } + }); TOCK(fill); return arr; } @@ -21,9 +28,12 @@ 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()), + [&](tbb::blocked_range r) { + for ( size_t i = r.begin(); i < r.end(); ++i) { + x[i] = a * x[i] + y[i]; + } + }); TOCK(saxpy); } @@ -31,9 +41,18 @@ 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)0, + [&](tbb::blocked_range r, T local_res) { + for ( size_t i = r.begin(); i < r.end(); ++i ) { + local_res += x[i] * y[i]; + } + return local_res; + }, + []( T x, T y) { + return x + y; + }); ret = std::sqrt(ret); TOCK(sqrtdot); return ret; @@ -43,10 +62,21 @@ 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]; - } + ret = tbb::parallel_reduce( + tbb::blocked_range(1, x.size()), + x[0], + [&] (tbb::blocked_range r, T local_res) { + for ( size_t i = r.begin(); i < r.end(); ++i) { + if ( x[i] < local_res) { + local_res = x[i]; + } + } + return local_res; + }, + [&] (T x, T y) { + return x < y ? x : y; + } + ); TOCK(minvalue); return ret; } @@ -55,14 +85,25 @@ 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]); + std::mutex mtx; + res.reserve( 2 * std::min(x.size(), y.size())); + tbb::parallel_for( + tbb::blocked_range(0, std::min(x.size(), y.size())), + [&] (tbb::blocked_range r) { + std::vector tmp_vec; + for (size_t i = r.begin(); i < r.end(); i++) { + if (x[i] > y[i]) { + tmp_vec.push_back(x[i]); + } else if (y[i] > x[i] && y[i] > 0.5f) { + tmp_vec.push_back(y[i]); + tmp_vec.push_back(x[i] * y[i]); + } + } + + std::lock_guard lck{mtx}; + std::copy(tmp_vec.begin(), tmp_vec.end(), std::back_inserter(res)); } - } + ); TOCK(magicfilter); return res; } @@ -71,10 +112,24 @@ 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; - } + // 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)0, + [&] (tbb::blocked_range r, T local_res, auto 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; + }, + [] (T x, T y) { + return x + y; + } + ); TOCK(scanner); return ret; } @@ -100,3 +155,28 @@ int main() { return 0; } +// Before + // fill: 1.23536s + // fill: 1.25023s + // saxpy: 0.048762s + // sqrtdot: 0.086141s + // 5165.4 + // minvalue: 0.07746s + // -1.11803 + // magicfilter: 0.426949s + // 55924034 + // scanner: 0.080046s + // 5.28566e+07 + +// After Modified + // fill: 0.256878s + // fill: 0.264094s + // saxpy: 0.03981s + // sqrtdot: 1.18658s + // 5792.62 + // minvalue: 0.01506s + // -1.11803 + // magicfilter: 0.183792s + // 55924034 + // scanner: 0.032603s + // 5.28591e+07 \ No newline at end of file diff --git a/run.sh b/run.sh index 99e6ef6..4f67a99 100755 --- a/run.sh +++ b/run.sh @@ -1,5 +1,5 @@ #!/bin/sh set -e -cmake -B build +cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/Users/yangzhikai/farewell/cpp_review/vcpkg/scripts/buildsystems/vcpkg.cmake cmake --build build build/main