1

In C++ I would like two for loops to execute at the same time and not have one wait for the other one to go first or wait for it to end.
I would like the two for loops (or more) to finish the loops in the same speed it would take one loop of the same size to finish.

I know it's been asked and answered, but not in an example this simple. I'm hoping to solve this specific problem. I worked combinations of pragma omp code examples and couldn't get the result.

#include <iostream>
using namespace std;

#define N 5

int main(void) { 
    int i;
    for (i = 0; i < N; i++) {
        cout << "This is line ONE \n";
    };

    #pragma omp parallel
    #pragma omp for             
    for (i = 0; i < N; i++) {
        cout << "This is line TWO \n";
    };
};

Compiling
$ g++ parallel.cpp -fopenmp && ./a.out

The output of the code is this, in the time it takes to run two loops...

This is line ONE
This is line ONE
This is line ONE
This is line ONE
This is line ONE
This is line TWO
This is line TWO
This is line TWO
This is line TWO
This is line TWO  

The output I would like is this They don't have to print one after the other like this, but I would think they would if they were both getting to the print part of the loops at the same times. What I really need is for the loops to start and finish at the same time (with the loops being equal).

This is line ONE
This is line TWO
This is line ONE
This is line TWO
This is line ONE
This is line TWO
This is line ONE
This is line TWO
This is line ONE
This is line TWO

There's this Q&A here, but I don't quite understand the undeclared foo and the //do stuff with item parts. What kinda stuff? What item? I have not been able to extrapolate from examples online to make what I need happen.

13
  • 3
    "I know it's been asked and answered" Where? Which part is missing in that answer? Why is your question different? Commented Jan 30, 2022 at 14:15
  • 3
    This seems to be a meta.stackexchange.com/questions/66377/what-is-the-xy-problem I.e. you want to do one thing (X) which is hard, because you think it would make doing something else (Y) easy. Try a different approach. Why don't you want to do cout << "This is line ONE \n"; cout << "This is line TWO \n"; in a single loop, it would get you exactly the desired output. Commented Jan 30, 2022 at 14:17
  • 1
    Does #pragma omp parallel work backwards on loops that have already finished? Commented Jan 30, 2022 at 14:55
  • 3
    Is this a realistic example code? cout use a lock internally to prevent any data race so it cannot run truly in parallel. The same thing apply for printf (and certainly all similar functions). You appear not to need parallelism but concurrency which is totally different. You can do concurrency with multiple threads but synchronizing at fine grain is clearly not efficient on modern hardware (unless the two threads run in the same core in separate hardware threads. OpenMP appears not to be the good tool here: it does not provides concurrency features (although they can be emulated). Commented Jan 30, 2022 at 15:43
  • 1
    You can start 2 independent threads, one looping to read the sensor and the other looping to control the motor. Commented Jan 30, 2022 at 15:48

2 Answers 2

3

As already mentioned in the comments that OpenMP may not be the best solution to do so, but if you wish to do it with OpenMP, I suggest the following:

Use sections to start 2 threads, and communicate between the threads by using shared variables. The important thing is to use atomic operation to read (#pragma omp atomic read seq_cst) and to write (#pragma omp atomic write seq_cst) these variables. Here is an example:

#pragma omp parallel num_threads(2)
#pragma omp sections
{                     
    #pragma omp section
    {
        //This is the sensor controlling part
            
        while(exit_condition)
        {
            sensor_state = read_sensor(); 
            
            // Read the currect state of motor from other thread
            #pragma omp atomic read seq_cst
            motor_state=shared_motor_state;
            
            // Based on the motor_state and sensor state send
            // a command to the other thread to control the motor
            // or wait for the motor to be ready in a loop, etc.
            
            #pragma omp atomic write seq_cst
            shared_motor_command= //whaterver you wish ;
        }
    }

    #pragma omp section
    {
        //This is the motor controlling part           
        while(exit_condition)
        {
            // read motor command form other thread
            #pragma omp atomic read seq_cst
            motor_command = shared_motor_command;

            // Do whatewer you have to to based on motor command and
            // You can set the state of motor by the following line

            #pragma omp atomic write seq_cst
            shared_motor_state= //what you need to pass to the other thread


        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. I am in the process of installing the libraries to try this. I will compare.
0

I think the issue is that you are not trying to parallelize two loops but instead you try to parallelize the work of one loop. If you would add std::cout << "Hello from thread: " << omp_get_thread_num() << "\n"; to your second loop you would see:

This is line TWO
Hello from thread: 0
This is line TWO
Hello from thread: 1
This is line TWO
Hello from thread: 2
This is line TWO
Hello from thread: 3
This is line TWO  
Hello from thread: 0

Depending on the assignment to threads, with four threads being the default amount of threads (often number of cores), the order might vary: example (0,1,2,3,0) could be (0,2,3,1,0)

So what you do is that the first loop is run in serial and then (4 or more/less) threads run the second loop in parallel.

The question is if you REALLY want to use OpenMP to parallelize your code. If so you could do something similar to:

#include <iostream>
#include <omp.h>
#include <String.h>


int main() {

    #pragma omp parallel for schedule(static)
    for(int i = 0; i < 10; i++){
        int tid = omp_get_thread_num();
        if (tid%2==0) {
            std::cout << "This is line ONE" << "\n";
        } else {
            std::cout << "This is line TWO" << "\n";
        }
    }
    return 0;
}

Where based on the threadID - if it is an even thread it will do task 1, if it is an uneven thread it will do task 2. But as many other commenters have commented, maybe you should consider using p_threads depending on the task.

1 Comment

It runs for a little bit with the motor and sensor. Now well. Then I get a Segmentation fault (core dumped). Now I feel like I should post the motor and sensor code somewhere. For the record, I don't get errors in the motor / sensor code if I run it without. The motor works great if I comment out all the sensor code. That's what clogs up the motors pulses. I'm sorry this became about motors and don't have the motor code in the OP.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.