joysticko
joysticko

Reputation: 39

Can one function operate on few threads?

I have a question about threads. For example I've got code like this

void xyz(int x){

...
}

int main{

for(int i=0;i<n;i++){
xyz(n);
}

}

The question is if I can modife code (and how?) in order to first thread call a function with arguments 1 to n/2 and second thread call a function with arguments from n/2 to n.

Thank you in advance

Upvotes: 0

Views: 81

Answers (3)

Nikos C.
Nikos C.

Reputation: 51850

Sure. You can use <thread> for this:

#include <thread>

// The function we want to execute on the new thread.
void xyz(int start, int end)
{
    for (int i = start; i < end; ++i) {
        // ...
    }
}

// Start threads.
std::thread t1(xyz, 1, n / 2);
std::thread t2(xyz, n / 2, n);

// Wait for threads to finish.
t1.join();
t2.join();

If you're using GCC or Clang, don't forget to append -pthread to your link command if you get a link error (example: gcc -std=c++14 myfile.cpp -pthread.)

Upvotes: 1

You should read some tutorial about multi-threading. I recommend this Pthread tutorial, since you could apply the concepts to C++11 threads (whose model is close to POSIX threads).

A function can be used in several threads if it is reentrant.

You might synchronize with mutexes your critical sections, and use condition variables. You should avoid data races.

In some cases, you could use atomic operations.

(your question is too broad and unclear; an entire book is needed to answer it)

You might also be interested by OpenMP, OpenACC, OpenCL.

Be aware that threads are quite expensive resources. Each has its own call stack (of one or a few megabytes), and you generally don't want to have much more runnable threads than you have available cores. As a rule of thumb, avoid (on a common desktop or laptop computer) having more than a dozen of runnable threads (and more than a few hundreds of idle ones, and probably less). But YMMV; I prefer to have less than a dozen threads, and I am trying to have less threads than what std::thread::hardware_concurrency gives.

Both answers from Nikos C. and from Maroš Beťko are using two threads. You could use a few more, but it probably would be unreasonable and inefficient to use a lot more of them (e.g. a hundred threads), at least on some ordinary computer. The optimal amount of threads is computer (and software and system) specific. You might make it a configurable parameter of your program. On supercomputers, you could mix multi-threading with some MPI approach. On datacenters or clusters, you might consider a MapReduce approach.

When benchmarking, don't forget to enable compiler optimizations. If using GCC or Clang, compile with -O2 -march=native at least.

Upvotes: 0

Maroš Beťko
Maroš Beťko

Reputation: 2329

Here is a simple solution using std::async and a lambda function capturing your n:

#include <future>

int main() {
    size_t n = 666;

    auto f1 = std::async(std::launch::async, [n]() { 
        for (size_t i = 0; i < n / 2; ++i)
            xyz(i);
    });
    auto f2 = std::async(std::launch::async, [n]() { 
        for (size_t i = n/2; i < n; ++i)
            xyz(i);
    });

    f1.wait();
    f2.wait();
    return 0;
}

Each call to std::async creates a new thread and then calling wait() on the std::futures returned by async, makes sure the program doesn't return before those threads finishing.

Upvotes: 1

Related Questions