Friday, May 10, 2024

MultiThreading: Understanding Thread-Local Data in C++

In multi-threaded program, `thread_local` allows each thread to have its own separate instance of variable and changes made to it in one thread would not affects its value in another thread.


Program:

#include <iostream>

#include <thread>

#include <mutex>

 

using namespace std;

std::mutex mutexCout;

 

thread_local string welcomeMessage = "Executing ";

 

void checkThreadLocal(string const& threadName)

{

welcomeMessage.append(threadName);

           lock_guard<mutex> guard(mutexCout);

           cout << welcomeMessage << endl;

}

 

int main()

{

           thread t1(checkThreadLocal, "thread1 ");

           thread t2(checkThreadLocal, "thread2 ");

           thread t3(checkThreadLocal, "thread3 ");

           thread t4(checkThreadLocal, "thread4 ");

 

           t1.join();

           t2.join();

           t3.join();

           t4.join();

}


Output:

Executing thread1

Executing thread2

Executing thread3

Executing thread4


Output of program shows that local string is created for each string welcomeMessage


When to use thread_local ?
  1. Thread-specific data: Sometimes, you need data that is specific to each thread. For example, you might want to maintain a thread-local cache or store thread-specific configuration settings. thread_local allows you to declare variables that are unique to each thread, making it convenient to work with thread-specific data.
  2. Thread safety: In multi-threaded programs, global variables are shared among threads and can lead to race conditions if not properly synchronized. By using thread_local, you can avoid race conditions by ensuring that each thread has its own copy of the variable. This can simplify thread synchronization and improve thread safety.
  3. Performance optimization: In some cases, using thread-local variables can improve performance by reducing contention for shared resources. For example, if multiple threads frequently access a global variable, using thread_local to declare a separate copy of the variable for each thread can reduce cache invalidation and contention, leading to better performance.
  4. Avoiding mutex overhead: In scenarios where thread-local variables can replace the need for mutexes or other synchronization mechanisms, using thread_local can help avoid the overhead associated with locking and unlocking mutexes, leading to better performance.

Saturday, March 2, 2024

Execution Policy in C++17

𝐂++𝟏𝟕 introduced a feature called 𝐞𝐱𝐞𝐜𝐮𝐭𝐢𝐨𝐧 𝐩𝐨𝐥𝐢𝐜𝐲, which lets you define if you want the algorithm to run sequentially, in parallel, or in parallel with vectorization.


This feature is helpful for performance improvements, especially when dealing with large datasets.

Below is an example: