Prepare the subroutine to be run in a thread,
public class data { public int a,b; public double sum;} public static void harmonic(object obj){ var local = (data)obj; local.sum=0; for(int i=local.a;i<local.b;i++)local.sum+=1.0/i; }
Create a Main function that reads—from the command-line—two parameters, the number of threads to be created and the number of terms in the harmonic sum to calculate,
int nthreads = 1, nterms = (int)1e8; /* default values */ foreach(var arg in args) { var words = arg.Split(':'); if(words[0]=="-threads") nthreads=int.Parse(words[1]); if(words[0]=="-terms" ) nterms =(int)float.Parse(words[1]); }
Prepare data-objects to be used locally in separate threads,
data[] x = new data[nthreads]; for(int i=0;i<nthreads;i++) { x[i]= new data(); x[i].a = 1 + nterms/nthreads*i; x[i].b = 1 + nterms/nthreads*(i+1); } x[x.Length-1].b=nterms+1; /* the enpoint might need adjustment */
Prepare the threads and run them, hopefully in parallel (if there is enough processors in your box),
var threads = new Thread[nthreads]; for(int i=0;i<nthreads;i++) { threads[i] = new Thread(harm); /* create a thread */ threads[i].Start(x[i]); /* run it with x[i] as argument to "harmonic" */ }
Join the threads,
for(int i=0;i<nthreads;i++) threads[i].Join();
Calculate the total sum,
double total=0; for(int i=0;i<nthreads;i++) total+=x[i].sum;
Using the POSIX "time"-utility measure the processor times running your Main with different number of threads. Something like
N=1e8 TIME = time --portability --append --output $@ Out.txt : main.exe Makefile >$@ $(TIME) mono $< -terms:$N -threads:1 >>$@ $(TIME) mono $< -terms:$N -threads:2 >>$@ $(TIME) mono $< -terms:$N -threads:3 >>$@ $(TIME) mono $< -terms:$N -threads:4 >>$@
Now calculate the harmonic sum using "Parallel.For",
double sum=0; Parallel.For( 1, N+1, delegate(int i){sum+=1.0/i;} );Time it and explain why it runs slower than the serial for-loop even with one thread.