Objectives
We would like to :
Notes
   -  Start a parallel program.
   
 -  
#pragma omp parallel
    -  
#include < omp.h>
   -  link with 
-fopenmp
    -  As we said before once in the parallel pragma block each thread runs the code.
   
 -  Task: Write hello world in parallel.
   
       -  To clean printing, 
       
 -  
 #pragma omp critical
        -  Only one thread at a time can execute the next code block.
   
 
    -  omp_set_num_threads(), to change the number of threads.
   
 -  omp_get_thread_num() gives us a unique id for each thread.
   
        -  Clean up your code so you can get a hello from each tread, 
   
 
    -   Can we nest parallel, yes we can.
   
       -  Declare a parallel block inside the parallel block.
       
 -  Get a new id for each thread, and print each out.
       
 -  Not so impressive, everyone just runs one thread.
   
 
    -  
omp_set_max_active_levels(int n );  will let you have n levels of parallelism
    -  Try the last code again.
   
 -   If we want, we can limit the threads in a parallel section
   
       -  
 #pragma omp parallel num_threads(int n)
    
    -  There are more directives we can put there, but this will do for now.
   
 -  #pragma omp barrier 
   
       -  Will stop all threads until the barrier is reached.
   
 
    -  Remember, the for loop.
   
       -  
 #pragma omp for
       
           -  This uses the active threads.
           
 -  If the loop runs k times with b threads, n = k/b
           
               -  Thread 0 gets i = 0, k/b-1
               
 -  Thread 1 get  i = k/b to 2k/b -1
               
 -  Thread n-1 gets i = k/b(n-1) to nk/b -1
           
 
        
    
    -  Rules parallel for loops
   
       -  OMP needs to be able to compute the number of iterations.
       
 -  No break, return, exit or goto
       
 -  index update must be by a fixed amount
       
 -  Loop variable is private, no changes inside the loop, only for increment..
   
 
    -  Remember omp_get_wtime
   
 -  One way to compute pi is by throwing  'uniform' darts at a dart board.
   
        -  If the probability of hitting the box the dartboard in which the dartboard is inscribed is 100%, the probability of hitting the board is the area of the board
        
 -  Look at a r=1 dartboard, only 1/4 of the board (why)
        
 -  Centered at 0,0
        
 -  Use the random number generator to "throw a dart"
        
 -  Seed with threadID * time
        
 -  Record the hits
        
 -  Pi = 4 * hits/trials