Sequential and parallel addition of 2 vectors I have done sequential and parallel addition of 2 vectors that I have filled with some dummy values. I am also measuring the time of execution for both, sequential and parallel execution.

#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;
#include &lt;functional&gt;
#include &lt;chrono&gt;
#include &lt;cassert&gt;
#include &lt;thread&gt;

#define NUM_OF_THREADS 8
#define VECTOR_SIZE    512

using time_point = std::chrono::high_resolution_clock::time_point;

template&lt;typename T&gt;
std::vector&lt;T&gt; operator+(std::vector&lt;T&gt; const&amp; first, std::vector&lt;T&gt; const&amp; second)
{
    assert(first.size() == second.size());

    std::vector&lt;T&gt; result;
    result.reserve(first.size());

    std::transform(first.begin(), first.end(), second.begin(), std::back_inserter(result), std::plus&lt;T&gt;());
    return result;
}

template&lt;typename T&gt;
void parallel_addition(std::vector&lt;T&gt;&amp; result,
                       std::vector&lt;T&gt; const&amp; first,
                       std::vector&lt;T&gt; const&amp; second,
                       size_t lower_bound,
                       size_t upper_bound)
{
    for (size_t i = lower_bound; i &lt; upper_bound; i++)
    {
        result[i] = first[i] + second[i];
    }
}

int main(int argc, char *argv[])
{
    std::vector&lt;int&gt; first_vec, second_vec;

    /* Filling up the vectors with dummy values */
    for (int i = 1; i &lt;= VECTOR_SIZE; i++)
    {
        first_vec.push_back(i);
        second_vec.push_back(i);
    }

    /* Sequential addition of vectors */
    time_point t1_seq = std::chrono::high_resolution_clock::now();
    std::vector&lt;int&gt; sequential_result = first_vec + second_vec;
    time_point t2_seq = std::chrono::high_resolution_clock::now();
    auto duration_seq = std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(t2_seq - t1_seq).count();
    std::cout &lt;&lt; "Sequential addition of vectors - execution time: " &lt;&lt; duration_seq &lt;&lt; "us" &lt;&lt; std::endl;

    /* Parallel addition of vectors */
    std::vector&lt;std::thread&gt; threads;
    std::vector&lt;int&gt; parallel_result(VECTOR_SIZE);

    time_point t1_par = std::chrono::high_resolution_clock::now();

    for (int i = 0; i &lt; NUM_OF_THREADS; i++)
    {
        threads.push_back(std::thread(parallel_addition&lt;int&gt;,
                                      std::ref(parallel_result),
                                      first_vec,
                                      second_vec,
                                      i * (VECTOR_SIZE / NUM_OF_THREADS),
                                      (i + 1) * (VECTOR_SIZE / NUM_OF_THREADS)));
    }

    for (auto &amp;thread : threads)
    {
        thread.join();
    }

    time_point t2_par = std::chrono::high_resolution_clock::now();
    auto duration_par = std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(t2_par - t1_par).count();
    std::cout &lt;&lt; "Parallel (" &lt;&lt; NUM_OF_THREADS &lt;&lt; " threads) addition of vectors - execution time: " &lt;&lt; duration_par &lt;&lt; "us" &lt;&lt; std::endl;

    return 0;
}


Despite style review, can you also tell me if there is another, better, approach to addition of two vectors in multiple threads?
My intention was to write in C++17.
#define NUM_OF_THREADS 8
#define VECTOR_SIZE    512


Don't use #define for constants or "functions" (⧺ES.31)



using time_point = std::chrono::high_resolution_clock::time_point;


Good!  bring down just the stuff you need, and give it a friendly name.  I think

using std::chrono::high_resolution_clock::time_point;


would be the same thing, and is the usual way of importing symbols from a library’s namespace.



assert(first.size() == second.size());


That will not do anything in a release build, you know.

If you really want checking, make a precondition that always works.  The GSL support library has Expects that can be programmed at compile time to assert, throw, or die.



In general operator+ looks good!  You are using a value return, and you ensure NVRO takes place.  You reserve the vector size.  You use STL algorithms.



for (int i = 1; i &lt;= VECTOR_SIZE; i++)
{
    first_vec.push_back(i);
    second_vec.push_back(i);
}


There is a standard algorithm for that.



time_point t1_seq = std::chrono::high_resolution_clock::now();
⋮


Use auto (almost everywhere).

since there is no code-movement barrier, your benchmark might not be accurate.  



for (auto &amp;thread : threads)


Good!  You use the range-for where you can.