# include # include # include # include # include using namespace std; int main ( int argc, char *argv[] ); int i4_div_rounded ( int a, int b ); int i4_huge ( void ); int i4_sign ( int i ); void task_divide ( int task_number, int proc_first, int proc_last ); void timestamp ( void ); //****************************************************************************80 int main ( int argc, char *argv[] ) //****************************************************************************80 // // Purpose: // // MAIN is the main program for TASK_DIVISION. // // Discussion: // // This program simply demonstrates how one might automate the // assignment of T tasks to P processors, assuming that the assignment // is to be beforehand. // // In that case, we just want to make sure that we assign each task // to a processor, that we assign about the same number of tasks // to each processor, and that we assign each processor a contiguous // range of tasks, say tasks I_LO to I_HI. // // The routine that is called simulates this process. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 21 October 2007 // // Author: // // John Burkardt // { int proc_first; int proc_last; int task_number; timestamp ( ); cout << "\n"; cout << "TASK_DIVISION:\n"; cout << " C++ version\n"; cout << "\n"; cout << " Demonstrate how to automate the assignment of\n"; cout << " T tasks among P processors.\n"; task_number = 23; proc_first = 0; proc_last = 3; task_divide ( task_number, proc_first, proc_last ); task_number = 17; proc_first = 1; proc_last = 6; task_divide ( task_number, proc_first, proc_last ); task_number = 17; proc_first = 4; proc_last = 6; task_divide ( task_number, proc_first, proc_last ); task_number = 5; proc_first = -2; proc_last = 6; task_divide ( task_number, proc_first, proc_last ); task_number = 5; proc_first = 0; proc_last = 4; task_divide ( task_number, proc_first, proc_last ); task_number = 5; proc_first = 0; proc_last = 0; task_divide ( task_number, proc_first, proc_last ); task_number = 1000; proc_first = 1; proc_last = 17; task_divide ( task_number, proc_first, proc_last ); cout << "\n"; cout << "TASK_DIVISION:\n"; cout << " Normal end of execution.\n"; cout << "\n"; timestamp ( ); return 0; } //****************************************************************************80 int i4_div_rounded ( int a, int b ) //****************************************************************************80 // // Purpose: // // I4_DIV_ROUNDED computes the rounded result of I4 division. // // Discussion: // // This routine computes C = A / B, where A, B and C are integers // and C is the closest integer value to the exact real result. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 21 October 2007 // // Author: // // John Burkardt // // Parameters: // // Input, int A, B, the number to be divided, // and the divisor. // // Output, int I4_DIV_ROUNDED, the rounded result // of the division. // { int a_abs; int b_abs; int c; int c_abs; int c_s; if ( a == 0 ) { c_abs = i4_huge ( ); c_s = i4_sign ( b ); } else { a_abs = abs ( a ); b_abs = abs ( b ); c_s = i4_sign ( a ) * i4_sign ( b ); c_abs = a_abs / b_abs; if ( ( 2 * c_abs + 1 ) * b_abs < 2 * a_abs ) { c_abs = c_abs + 1; } } c = c_s * c_abs; return c; } //****************************************************************************80 int i4_huge ( void ) //****************************************************************************80 // // Purpose: // // I4_HUGE returns a "huge" I4. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 16 May 2003 // // Author: // // John Burkardt // // Parameters: // // Output, int I4_HUGE, a "huge" I4. // { return 2147483647; } //****************************************************************************80 int i4_sign ( int i ) //****************************************************************************80 // // Purpose: // // I4_SIGN returns the sign of an I4. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 27 March 2004 // // Author: // // John Burkardt // // Parameters: // // Input, int I, the integer whose sign is desired. // // Output, int I4_SIGN, the sign of I. { int value; if ( i < 0 ) { value = -1; } else { value = 1; } return value; } //****************************************************************************80 void task_divide ( int task_number, int proc_first, int proc_last ) //****************************************************************************80 // // Purpose: // // TASK_DIVIDE divides tasks among processors. // // Discussion: // // This routine assigns each of T tasks to P processors, assuming that // the assignment is to be beforehand. // // In that case, we just want to make sure that we assign each task // to a processor, that we assign about the same number of tasks // to each processor, and that we assign each processor a contiguous // range of tasks, say tasks I_LO to I_HI. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 20 October 2007 // // Author: // // John Burkardt // // Parameters: // // Input, int TASK_NUMBER, the number of tasks. // // Input, int PROC_FIRST, PROC_LAST, the first and last processors. // { int i_hi; int i_lo; int proc; int proc_number; int proc_remain; int task_proc; int task_remain; proc_number = proc_last + 1 - proc_first; cout << "\n"; cout << "TASK_DIVIDE\n"; cout << " Divide T tasks among P processors.\n"; cout << "\n"; cout << " P(first) = " << proc_first << "\n"; cout << " P(last) = " << proc_last << "\n"; cout << "\n"; cout << " T = " << task_number << "\n"; cout << " P = " << proc_number << "\n"; cout << "\n"; cout << " Processor Tasks First Last\n"; cout << "\n"; i_hi = 0; task_remain = task_number; proc_remain = proc_number; for ( proc = proc_first; proc <= proc_last; proc++ ) { task_proc = i4_div_rounded ( task_remain, proc_remain ); proc_remain = proc_remain - 1; task_remain = task_remain - task_proc; i_lo = i_hi + 1; i_hi = i_hi + task_proc; cout << " " << setw(8) << proc << " " << setw(8) << task_proc << " " << setw(8) << i_lo << " " << setw(8) << i_hi << "\n"; } return; } //****************************************************************************80 void timestamp ( void ) //****************************************************************************80 // // Purpose: // // TIMESTAMP prints the current YMDHMS date as a time stamp. // // Example: // // May 31 2001 09:45:54 AM // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 03 October 2003 // // Author: // // John Burkardt // // Parameters: // // None // { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; size_t len; time_t now; now = time ( NULL ); tm = localtime ( &now ); len = strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); cout << time_buffer << "\n"; return; # undef TIME_SIZE }