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.