How can I arrange to only use @threads if the number of iteration is higher than minimum?

I need to run @threads before “for loop” only if the number of iteration is bigger than a predetermined value (called min_iter here ), such as

@threads min_iter for i in ..., 

Any idea?

Any idea?

It’s a bit old, but perhaps still useful:

Another: Optional macro invocation - #21 by goerz

Thank you for sharing, but the useful link was removed.

Thank you very much for sharing the link. I have read the code there, but can you please give me an example how to implement it, such as by example?

You could try using Polyester.jl with a batch size instead of Threads.@threads.

I haven’t done it, but it looks like you should be able to do something like this:

@threadsif n>100 for i=1:n
   dowork()
end

Make a macro @threadsif cond expr expanding to cond ? @threads(expr) : expr?

Thanks for your reply. Can you help me in doing it, I dont know actually how to do ti.

I got it, thank you very much!
Do you know, how to make it more fancy by choosing number of threads based on the size of n?

Do you think the performance with @batch would be the same as in @threads?

Well I’m no expert on this, but it seems like what you’re doing is at the limit of serial vs threads efficiency and Polyester.jl is exactly aimed at reducing the threads overhead. Probably @Elrod is more qualified to answer this.

I see. Thank you very much for your support!

If it is dominated by threading or scheduling overhead, then Polyester should help.
Also, as stated,

@batch minbatch=min_iter for i in ...

should work and do what you want. It won’t thread if less than min_iter iterations, and it will make sure each thread has at least min_iter iterations (so if the total number of iterations = 2.9min_iter, it’ll use 2 threads). This slower ramp up should also help / let you avoid using more threads than is profitable.

3 Likes

@Elrod
I have compared between the @batch and the method here:
Optional macro invocation

function ss()
dt = 0.001;     
tmin = 0;  
tmax = 5;
timeSim = tmin:dt:tmax;
A_Mat = spzeros(9,9); 
for i in 1:9
  A_Mat[i,i] = 1;
end
I_Mat = ones(9,3);
  iter = 0;
  for t in timeSim
      iter += 1;
      n=101
      #@threadsif n>100 for i in 1:n #by using it the time is  182 ms
      @batch minbatch=15 for i in 1:n   #by using it the time is  879.872 ms
      V_Mat = A_Mat \ I_Mat;
    end
end
end
using SparseArrays;
using LinearAlgebra;
using .Threads
using Polyester
using BenchmarkTools
@btime ss()

Any reason why @batch results in a really big number comparing with conditional thread @threadsif ?

I assume your real problem is much larger? For a 9x9 array, it’d be much faster to use a dense matrix.

But, the problem is that Polyester is converting Arrays into a custom array type that apparently doesn’t have these methods implemented. I’ll get around to implementing them some day.
For now, you can work around it; this seems to be enough to hide the arrays and pass them through as is:

function ss()
       dt = 0.001;
       tmin = 0;
       tmax = 5;
       timeSim = tmin:dt:tmax;
       A_Mat = zeros(9,9);
       for i in 1:9
         A_Mat[i,i] = 1;
       end
       I_Mat = ones(9,3);
         iter = 0; A_Matr = (Am = A_Mat,); I_Matr = (Im = I_Mat,);
         for t in timeSim
             iter += 1;
             n=101
             #@threadsif n>100 for i in 1:n #by using it the time is  182 ms
             @batch minbatch=15 for i in 1:n   #by using it the time is  879.872 ms
             V_Mat = A_Matr.Am \ I_Matr.Im;
           end
       end
       end
ss (generic function with 1 method)
2 Likes

Thank you for your explanations. Yes, my real problem is much larger, thus, I am using a sparse Matrix