// Parallel loop
#pragma omp parallel for
for (int i = 0; i < size; ++i) {
    // Code that can be executed in parallel
    data[i] *= 2;  // Example: Doubling each element

    // Code that cannot be executed in parallel; {} is not necessary, it's used to improve readability and avoid unintended behavior.
    #pragma omp critical
    {
        result += data[i];  // Example: Accumulating to a shared variable
    }
}
// Parallel loop with reduction
#pragma omp parallel for reduction(+:result)
for (int i = 0; i < size; ++i) {
    // Code that can be executed in parallel
    data[i] *= 2;  // Example: Doubling each element
    // Reduction operation
    result += data[i];
}

Benefits of Using reduction:

  1. Reduces overhead of the critical section.
  2. Automatically handles thread-local copies and merging.

Use the reduction clause for simpler operations and critical for more complex shared operations.

set the number of threads used for parallel execution

#pragma omp parallel for num_threads(4)
for (int i = 0; i < size; ++i) {
    data[i] *= 2; // Example operation: doubling each element
    int thread_id = omp_get_thread_num();
    std::cout << "Thread " << thread_id << " processed index " << i << "\n";
}