Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <thread>
- #include <vector>
- #include <chrono>
- #include <mutex>
- #include <string>
- #define SUM_THREASHOLD 32
- static std::mutex mtx;
- static void sum_krn(int a[], int l, int r, int* res, int thr_i)
- {
- int s = 0;
- mtx.lock();
- printf("[sum_krn] thread %d l %d r %d\n", thr_i, l, r);
- mtx.unlock();
- while(l <= r)
- s += a[l++];
- *res = s;
- }
- static void parallel_sum(int a[], int size, int* res, int threads)
- {
- std::vector<std::thread> workers;
- int n_workers;
- int i = 0, l, r, grain;
- if(threads == -1)
- threads = std::thread::hardware_concurrency();
- grain = size / threads;
- n_workers = threads - 1;
- printf("[parallel_sum] size %d threads %d grain %d\n",
- size, threads, grain);
- // skip if the array is too small
- if(size >= SUM_THREASHOLD)
- {
- for(i = 0; i < n_workers; ++i)
- {
- l = grain * i;
- r = grain * (i + 1);
- std::thread thr = std::thread(&sum_krn, a, l, r, res, i);
- workers.push_back(std::move(thr));
- }
- }
- sum_krn(a, grain * i, size - 1, res, i);
- for(i = 0; i < workers.size(); ++i)
- workers[i].join();
- }
- int main(int argc, char** argv)
- {
- int sz;
- int i;
- int sum;
- int threads = -1;
- std::vector<int> a;
- if(argc < 2)
- {
- fprintf(stderr, "usage: prog ARRAY_SIZE [N_THREADS]\n");
- return -1;
- }
- try {
- sz = std::stoi(argv[1]);
- if(argc >= 3)
- threads = std::stoi(argv[2]);
- }
- catch(const std::exception& e)
- {
- fprintf(stderr, "Failed to parse input args: %s\n", e.what());
- return -1;
- }
- a.resize(sz);
- for(i = 0; i < sz; i++)
- a[i] = i;
- auto tm_start = std::chrono::high_resolution_clock::now();
- parallel_sum(&a[0], sz, &sum, threads);
- auto tm_end = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double> tm_diff = tm_end - tm_start;
- double elapsed = tm_diff.count();
- printf("Elapsed time %f sec.\nSum = %d\n", elapsed, sum);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement