Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

Range in blocked_range<type>(start, end)

akhal
Beginner
343 Views
hej

I am very new to TBB. I have the following situation: since I am using only two available threads, so I have adjusted grainsize in parallel_for according to two threads.


#define size 10 //for example, though I have to use sizes like 1000 or 2000 ultimately
class myClass
{
double** my_a;

public:
myClass(double** arr) : my_a(arr) {}
void operator() (blocked_range& r) const
{
double** a = my_a;
int k = r.begin();

for(int i=k+1; i!=r.end(); i++)
for(int j=k+1; j!=r.end(); j++)
{

a -= a*a;

}
}
};
/*--------------------------------Main function code snippet-------------------------------------*/
double** a; // and then "a" is initialized for some values with "a" size as [size][size]
for(int k=0; k {

parallel_for(blocked_range(k, size, ceil(float(size-k)/2.0)), myClass(a));
}


Now this code works wrong. It only works correctly as desired when inside myClass body's for loops, I use condition checks for both i & j as:


for(int i=k+1; i!=size; i++)
for(int j=k+1; j!=size; j++)
{

a -= a*a;

}


I wonder this since according to normal TBB parallel_for, I am sending range(i,size); so in myClass body, I should be using r.end() for condition testing rather than using a global constant "size". What should I do? Please suggest a solution.
0 Kudos
7 Replies
RafSchietekat
Valued Contributor III
343 Views
Think tasks, not threads: don't let grainsize depend on number of threads. To involve size-k, replace blocked_range instead, because cost is not uniform along the range (it seems more like O((size-k)^2), but that should not be your first or even second or third concern.

(Edited) To see what's wrong, just make parallel_for serial (call the function object twice, once with [k,middle[, and once with [middle,size[) and trace the steps.
0 Kudos
akhal
Beginner
343 Views
Sorry I am confused by your last suggestion "To see what's wrong, just make parallel_for serial (call the function object twice, once with [k,middle[, and once with [middle,size[) and trace the steps". Do you mean I make for functor class a simple class and make its object in main function without using TBB's parallel_for? I dont understand how to make parallel_for serial ?
0 Kudos
RafSchietekat
Valued Contributor III
343 Views
I mean replace the call to parallel_for with two direct calls to the function object, which you keep as-is. That's one valid execution for parallel_for, so it should work in a correct program, but this way you'll be able to observe why it doesn't.
0 Kudos
akhal
Beginner
343 Views
Sorry I am too new to TBB and to programming in general. Do you mean inside the normal loop in main function, I should just call the constructor of my functor class "myClass" ? like
for(---)
myClass(a);

without changing the body of class "myClass" ? And this will make my program still working as-is but serially now?
0 Kudos
RafSchietekat
Valued Contributor III
343 Views
[bash]#if 1 // this must work:
myClass(a)(blocked_range(k, (k+size)/2)      );
myClass(a)(blocked_range(   (k+size)/2), size);
#else // before this could possibly work:
parallel_for(blocked_range(k, size, ceil(float(size-k)/2.0)), myClass(a));
#endif
[/bash]

0 Kudos
akhal
Beginner
343 Views
Thanks, but in place of "blocked_range", How is "blocked_range" working?? infact, it gives me compile time errors saying wrong arguments to blocked_range.
0 Kudos
RafSchietekat
Valued Contributor III
343 Views
Tap into your inner HTML/XML parser. :-)

(Added) The effect in this particular situation would probably be similar with task_scheduler_init() used to specify a single thread, but two calls to the function object, without involving TBB at all, should be more directly convincing.
0 Kudos
Reply