←to practical programming

Exercise "multiprocessing"

Tasks:

  1. 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;
            }
    

  2. 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]);
       }
    

  3. 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 */
    

  4. 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" */
       }
    

  5. Join the threads,

    for(int i=0;i<nthreads;i++) threads[i].Join();
    

  6. Calculate the total sum,

    double total=0; for(int i=0;i<nthreads;i++) total+=x[i].sum;
    

  7. 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 >>$@
    

  8. 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.