An alternate way to distribute the work load

  • Alternate way to distribute the work load for 2 threads:

                    values handled by thread 0
       |   |   |   |   |   |   |   |   |   |   |   |   |   |
       V   V   V   V   V   V   V   V   V   V   V   V   V   V
       |-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|      
         ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^
         |   |   |   |   |   |   |   |   |   |   |   |   |   |
                    values handled by thread 1
    
              Thread 0                Thread 1
                  |                        |
                  |                        |
                  V                        V
               Tmin[0]                 Tmin[1]
                   \                      /
                    \                    /
                     \                  /
                      \                /
                       \              /
    		      main thread
    			   |
    			   |
    			   V
    		      Actual minimum
    

The work load processed by thread s

  • The work load handled by the thread s is as follows:

  • The for-loop used to process the work load of thread s is:

       // n = # threads used
    
       for ( int i = s; i < MAX; i = i + n )
       {
    
       }
    

The alternate worker( ) function

  • The worker( ) has the parameter id which identifies the segment that the thread must process:

    void *worker(int *id)   // *id = identifies the series starting at s below
    {
       double my_min;
    
       int s = *id;                 // *id = 0, 1, 2, ...or (N-1)
    
       my_min = x[s];               // Initial value for the min
    
       for (int i = s+N; i < MAX; i = i + N )
          if ( x[i] < my_min )
             my_min = x[i];
    
       Tmin[s] = my_min;            // Save result in Tmin[s]
    
       pthread_exit(NULL);          // Thread exits
    
       Input x[ ]:   
          +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
          +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                    ^               ^               ^               ^       
                    |               |		|		|
                    s              s+N             s+2N            s+3N
    }

The alternate worker( ) function

  • Copy the argument *id into the variable s (more convenient):

    void *worker(int *id)   // *id = identifies the series starting at s below
    {
       double my_min;
    
       int s = *id;  // s = one of: 0, 1, 2, ...or (N-1)
    
       my_min = x[s];               // Initial value for the min
    
       for (int i = s+N; i < MAX; i = i + N )
          if ( x[i] < my_min )
             my_min = x[i];
    
       Tmin[s] = my_min;            // Save result in Tmin[s]
    
       pthread_exit(NULL);          // Thread exits
    
       Input x[ ]:   
          +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
          +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                    ^               ^               ^               ^       
                    |               |		|		|
                    s              s+N             s+2N            s+3N
    }

The alternate worker( ) function

  • Find the minimum value in the series of values starting at x[s]:

    void *worker(int *id)   // *id = identifies the series starting at s below
    {
       double my_min;
    
       int s = *id;  // s = one of: 0, 1, 2, ...or (N-1)
    
       my_min = x[s];               // Initial value for the min
    
       for (int i = s+N; i < MAX; i = i + N )  // N = # threads
          if ( x[i] < my_min )
             my_min = x[i];
    
       Tmin[s] = my_min;            // Save result in Tmin[s]
    
       pthread_exit(NULL);          // Thread exits
    
       Input x[ ]:   
          +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
          +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                    ^               ^               ^               ^       
                    |               |		|		|
                    s              s+N             s+2N            s+3N
    }

The alternate worker( ) function

  • Save the minimum value in Tmin[s] and exit:

    void *worker(int *id)   // *id = identifies the series starting at s below
    {
       double my_min;
    
       int s = *id;  // s = one of: 0, 1, 2, ...or (N-1)
    
       my_min = x[s];               // Initial value for the min
    
       for (int i = s+N; i < MAX; i = i + N )  // N = # threads
          if ( x[i] < my_min )
             my_min = x[i];
    
       Tmin[s] = my_min;            // Save result in Tmin[s]
    
       pthread_exit(NULL);          // Thread exits
    
       Input x[ ]:   
          +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
          |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
          +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
                    ^               ^               ^               ^       
                    |               |		|		|
                    s              s+N             s+2N            s+3N
    }

DEMO: demo/pthread/min-mt2.c (use euler to demo) -- why is its slower than min-mt1.c ???)