understanding the relation between using a thread and calling a function. |
Using a thread *is* calling a function. When a thread is created, it immediately begins executing the function you pass to its constructor. When the function returns, the thread ends.
I don't understand how we can use threads to compute this problem faster. |
You'd need to rewrite it in a way that makes it possible to call functions that don't need each other's results to make progress.
Take a simpler (and more parallelizable) task, calculate the sum of all numbers in a sequence:
a[0] + a[1] + a[2] + ... + a[N-1]
You can make a function call that adds the whole thing together:
1 2 3 4 5 6 7 8 9
|
#include <iostream>
#include <numeric>
#include <vector>
int main()
{
std::vector<int> data{100000, 1};
int result = std::accumulate(data.begin(), data.end(), 0);
std::cout << result << '\n';
}
|
There is nothing threads can do there.
But you can rewrite that program to make two function calls, one for each half of the sequence:
1 2 3 4 5 6 7 8 9 10 11 12
|
#include <iostream>
#include <numeric>
#include <vector>
int main()
{
std::vector<int> data{100000, 1};
size_t mid = data.size()/2;
int sum1 = std::accumulate(data.begin(), data.begin() + mid, 0);
int sum2 = std::accumulate(data.begin() + mid, data.end(), 0);
int result = sum1 + sum2;
std::cout << result;
}
|
now if you call one of these functions on a thread, it can make progress while the other function is also making progress. Once they are both done, you can combine the results:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
#include <iostream>
#include <numeric>
#include <vector>
#include <thread>
int main()
{
std::vector<int> data{100000, 1};
size_t mid = data.size()/2;
int sum1;
std::thread t([&]{sum1 = std::accumulate(data.begin(), data.begin() + mid, 0);});
int sum2 = std::accumulate(data.begin() + mid, data.end(), 0);
t.join();
int result = sum1 + sum2;
std::cout << result;
}
|
that does the same thing, in half the time if you have enough CPU cores
(note in this example, the two threads (main and t) never access the same variable: t reads from a[0]..a[mid-1] and writes to sum1, main reads from a[mid]..a[n-1] and writes to sum2. If two threads have to access the same variable, things get complicated.