Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreading to perform a single task in C++

Suppose I have this big_task() function that I can split between threads for speedup.

The way to solve that issue with multithreading is to call _beginthread() on each task of the function and then wait for all the threads to finish, right?

How do I know if that's gonna be efficient and actually benefit to minimize big_task() running time?

I also heard that multithreading efficiency depends on the platform and hardware of the client. That means that it's something I need to query in the beginning of my program as well..?

One more question, when coding in Windows, is it better to use CreateThread() rather than _beginthread()? I write cross platform applications but if CreateThread() is more efficient than I could specialize my code to use that in Windows.

like image 907
Pilpel Avatar asked Mar 15 '23 03:03

Pilpel


2 Answers

The way to solve that issue with multithreading is to call _beginthread() on each task of the function and then wait for all the threads to finish, right?

this way you will parallelize your big function, so yes thats true.

How do I know if that's gonna be efficient and actually benefit to minimize big_task() running time?

you must profile it. If your big function is executing code on CPU no I/O operations, then consider creating the same number of threads as number of cores in your CPU.

I also heard that multithreading efficiency depends on the platform and hardware of the client. That means that it's something I need to query in the beginning of my program as well..?

CPU with more cores will surely be faster than the one with fewer, you can look into PPL (win only), TBB, OpenMP libraries which makes sure tasks are run efficiently basing on number of CPU cores.

One more question, when coding in Windows, is it better to use CreateThread() rather than _beginthread()? I write cross platform applications but if CreateThread() is more efficient than I could specialize my code to use that in Windows.

if you want cross platform, then use std::thread or boost for that.

like image 197
marcinj Avatar answered Mar 16 '23 19:03

marcinj


I hope this will help you to get started.

To achieve speedup over single-threaded approach you need multi-core CPU. On single-core CPU additional thread will not increase the computation speed but it may help to make other functions work smooth (e.g. GUI) in the same time while doing CPU-intense work.

To utilize multi-core CPU you need to split the "big task" into chunks which can be executed in the same time and not affecting each other.

General flow:

  1. Put the chunks into a container. Set their status to "available".
  2. Create as many threads as you want (up to actual number of CPU cores is useful).
  3. This is thread function. They are executed in parallel.

    1. Try to grab first "available" chunk from the container and make it "busy". If no "available" chunk is found, exit thread.
    2. Process the chunk and make it "ready".
    3. Go back to (4)
  4. In main thread wait for all worker threads to finish. You may wait in a loop sleeping a second each step, checking if Ctrl-C is pressed. Or simply "join" (wait until thread exits) on all the threads.

  5. Gather all the chunks together and use the result of your computation.

Be aware that you need to take care of multiple threads accessing the same data because they may interfere with each other. For example, it is possible for multiple threads to take same chunk for processing in the same time. This problem can be solved with mutex (see boost::mutex).

There are other approaches to this problem as well. You can put your chunks into a message queue (FIFO) and let threads pop them out from the queue and put results into some other queue. If you extend this queue over the network you can employ several PCs doing the work.

For portability you can use boost::thread.

This is useful as well: boost::thread_group

like image 26
Domagoj Prelošćan Avatar answered Mar 16 '23 20:03

Domagoj Prelošćan