2

I have a C++ program that tries to process each line of array in parallel, and after one line completely finishes, it moves on to the next line. My current program creates a thread for each line of array, and join them after usage. But it seems that the program is wasting a lot of time on creating/closing threads.

Is there a way to create those threads just for one time, and for each line they wait for the slowest thread to finish and then execute functions for the next line?

Here is my sample code:

#include <iostream>
#include <thread>
using namespace std;
#define THREAD 5
int arr[2][10000];
void update_arr(int i, int j_s, int j_to){
    for (int j = j_s; j <= j_to; j++)
        arr[i%2][j]= arr[(i-1)%2][j]+2*arr[(i-1)%2][j-1];
}

int main(){
    for (int i = 0; i < 10000; i++) arr[0][i] = 1;
    for (int i = 1; i <= 10000; i++){
        thread t[THREAD];
        for (int ii = 0; ii < THREAD; ii++)
            t[ii] = thread(update_arr, i, ii * 10000 / THREAD, (ii+1) * 10000 / THREAD - 1);

        for (int ii = 0; ii < THREAD; ii++)
            t[ii].join();   
    }
    cout<<arr[1][9999]<<endl;
}
Nick
  • 155
  • 3
  • 2
    You'll have much better luck batching larger amounts of work into your threads. There's high overhead for creating and terminating threads. – Will Bickford Sep 19 '18 at 04:23
  • 1
    Make that `int const thread_count = 5;`. Macros are evil. Also, 2 and 10000 are so-called magic numbers that would benefit from having symbolic names assigned to them. – Ulrich Eckhardt Sep 19 '18 at 06:07
  • Possible duplicate of [Reusing thread in loop c++](https://stackoverflow.com/questions/26516683/reusing-thread-in-loop-c) – Tsyvarev Sep 19 '18 at 08:44
  • Google "c++ threadpool library" to find hits. The [boost implementation](https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/thread_pool.html) is usually a safe bet. – Hans Passant Sep 19 '18 at 08:55

1 Answers1

2

This problem, the relatively high cost of creating and destroying threads, is what a is intended to avoid. Note that the std::async class can be implemented using a thread pool (but that is not guaranteed), so you should consider using that first.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
  • It is implementation dependent if `std::async` is implemented in terms of a thread pool. – Galik Sep 19 '18 at 06:11
  • @Nick : A thread pool, in the simplest case, is a collection of _worker threads_ that all loop forever, pulling _tasks_ from a shared, blocking queue, and _performing_ those tasks. The tasks could be just function pointers, which the workers "perform" by calling them. More typically, there is some `Task` interface defined, with a method named `run()` or `call(...)`, or `execute()`, etc. and the tasks are objects that implement the interface. – Solomon Slow Sep 19 '18 at 13:24