Software Archive
Read-only legacy content
17061 Discussions

Data race problem

Ömer_Faruk_Kalkan
532 Views

P1 and P2 data race problems  are appear when I inspect program . I haven`t got experience about Cilk Plus. I guess error is occur in nested loop . What should I do ?

    char * primary;
    char * secondary;
    primary = ( char * ) malloc (size * 15);
    secondary = ( char * ) malloc (size);

    cilk::reducer_opadd<long>number (0);

.  .  .  .

    cilk_for (int i= 0; i < size ; ++i)
    {
        cilk_for (int j = 14;  j >= 0;  --j )
        {
            number += (primary [(14 -  j ) + ( i * 15)] * (pow (3 ,  j )));
        }

        if (secondary [number.get_value ()] == 0)
        {
            secondary [number.get_value ()] = 1;
        }
        number.set_value (0);
    }

.  .  .  .

 

0 Kudos
1 Solution
Barry_T_Intel
Employee
532 Views

A cilk_for loop runs all iterations of the loop in parallel. You have no need of "number" outside of the cilk_for loop, so why bother with the reducer? Instead write:

cilk_for (int i= 0; i < size ; ++i)
    {
        long number = 0;

        for (int j = 14;  j >= 0;  --j )
        {
            number += (primary [(14 -  j ) + ( i * 15)] * (pow (3 ,  j )));
        }
 
        if (secondary [number] == 0)
        {
            secondary [number] = 1;,
            count++;
        }
    }

Now each iteration of your loop has a private copy of "number." Of course, you've still got a race on "count". That may want to be an op_add reducer.

   - Barry

 

View solution in original post

0 Kudos
4 Replies
Barry_T_Intel
Employee
532 Views

Well, to start with, the value of a reducer in the middle of a parallel region is undefined, since the computation hasn't completed yet. I *think* what you want is to move the declaration of your reducer inside the outer cilk_for.

Of course, then there's the question of why you need the inner cilk_for at all. It's not all that much work. Then you can just move the declaration of "number" inside the cilk_for, and each of the cilk_for iterations will have their own copy.

    - Barry

0 Kudos
Ömer_Faruk_Kalkan
532 Views

 

I understood inner cilk_for is unnecessary . I have changed following way but data races are continuing.

exactly why the error is due ? Can show me over my code...

 

 cilk::reducer_opadd<long>count (0);

cilk_for (int i= 0; i < size ; ++i)
    {
        for (int j = 14;  j >= 0;  --j )
        {
            number += (primary [(14 -  j ) + ( i * 15)] * (pow (3 ,  j )));
        }

        if (secondary [number.get_value ()] == 0)
        {
            secondary [number.get_value ()] = 1;,
            count++;
        }

        number.set_value (0);
    }

 

Ekran 3Alıntısı.PNG

Ekran Alıntıs2ı.PNG

0 Kudos
Barry_T_Intel
Employee
533 Views

A cilk_for loop runs all iterations of the loop in parallel. You have no need of "number" outside of the cilk_for loop, so why bother with the reducer? Instead write:

cilk_for (int i= 0; i < size ; ++i)
    {
        long number = 0;

        for (int j = 14;  j >= 0;  --j )
        {
            number += (primary [(14 -  j ) + ( i * 15)] * (pow (3 ,  j )));
        }
 
        if (secondary [number] == 0)
        {
            secondary [number] = 1;,
            count++;
        }
    }

Now each iteration of your loop has a private copy of "number." Of course, you've still got a race on "count". That may want to be an op_add reducer.

   - Barry

 

0 Kudos
Ömer_Faruk_Kalkan
532 Views

I get it now. Data race problems were solved. Thank you very much :) Do you have resources that you recommend for learning parallel programming ? Where should I start ...

0 Kudos
Reply