user3751151
user3751151

Reputation: 9

Performing task level parallelism with dependent data

I have visual studio in which openMP 3.0 is not suported (which means it does not have tasks construct) the problem is one thread has to generate multiple sets of array of data and another thread has to work on that array of data for every completed set... is there any workarounds for this without using tasks?? it will be grateful if i can get any help. the code :

    int id = omp_get_thread_num();
    if (id == 0)
    {
        for (int k = 0; k < n; k++)
        {
            int f = k * r * c;
            for (int i = 0; i < r; i++)
            {
                int rw = i * c;
                for (int j = 0; j < c; j++)
                {
                    p[f + rw + j] = rand() % 65535;
                }
            }
            _sleep(500);
        }
    }
    if (id == 1)
    {
        _sleep(200);
        for (int k = 0; k < n; k++)
        {
            int f = k * r* c;
            cout << "\n" << k;
            for (int i = 0; i < r; i++)
            {
                int rw = i * c;
                for (int j = 0; j < c; j++)
                {
                    p[f + rw + j] *= sin(2 * 3.14 * (10.0 / 100.0) * k);
                }
            }
            Mat img(r, c, CV_16UC1, p);
            namedWindow("output", CV_WINDOW_AUTOSIZE);
            imshow("output", img);
            waitKey();
        }
    }
}
system("pause");

This program works but i dont know whether is it running in parallel or in serial or does any redundancy occurs...

Upvotes: 0

Views: 97

Answers (1)

Christophe
Christophe

Reputation: 73490

Yes, there are the standard C++11 threads, but there is some work required.

Use of threads / basic structure of your code:

I asume that you are using namespace std; . In addition you'll need:

#include <thread>
#include <chrono>

The trick is to to put your threaded code in a void function accepting as input your thread id, as well as the shared variables (by reference). For instance, I used this for a quick feasibility test (you'll have to fine tune/adapt the types/etc...):

void mytask (int id, int&n, int& r, int& c, double *p)
{
    if (id == 0)
    { ... }
    if (id == 1)
    { ... }
}

You also have to use the correct sleep function replacing you former one:

    this_thread::sleep_for (std::chrono::milliseconds(500));  //_sleep (500);

Then in your code you might launch your threads, after having declared and initialised the shared variables:

...
thread t1 (mytask, 0, n, r, c, p );  // create an launch threads
thread t2 (mytask, 1, n, r, c ,p );  // 

t1.join();   // wait for t1 to finish
t2.join();   // wait for t2 to finish 
...

That's for the basic concept. It works with VC2013 express without openMP, at least for the concept.

Shared data and synchronisation:

Now you'll also have to fine tune and check if there is competition between the two threads on the same variables, and may be use the or to serialize access.

The analysis of your algorithms shows that the first thread puts random numbers in a table, ant the second thread applies a formula on these results. This assumes that the first thread ALWAYS calculate the elements BEFORE the second uses them. However, you can't assume too much about the scheduling of the threads. The system could slow down one or even freeze one of them and resume it later.

So here an initial idea (but needs further ellaboration), using :

#include <atomic>

Define a shared protected variable that will store the outer loop counter (I suggest this here, because both threads access p[] using the same sequence):

atomic<int> line_ready=-1;  // U used here a global variable

In the producing thread, add at the end of the outer loop the line:

line_ready.store (k);    // sync: loop was processed from 0 to k. 

In the consuming thread, add at the begin of the outer loop the line:

while (k>line_ready.load()) // sync: read k to know if we have to wait for data
this_thread::sleep_for (std::chrono::milliseconds(100)); // wait 

This will wait for the data if it is not available. Now it's up to you !

Upvotes: 2

Related Questions