cs205-lecture-examples

Example codes used during Harvard CS205 lectures
git clone https://git.0xfab.ch/cs205-lecture-examples.git
Log | Files | Refs | README | LICENSE

taskbench.c (8372B)


      1 /****************************************************************************
      2 *                                                                           *
      3 *             OpenMP MicroBenchmark Suite - Version 3.1                     *
      4 *                                                                           *
      5 *                            produced by                                    *
      6 *                                                                           *
      7 *             Mark Bull, Fiona Reid and Nix Mc Donnell                      *
      8 *                                                                           *
      9 *                                at                                         *
     10 *                                                                           *
     11 *                Edinburgh Parallel Computing Centre                        *
     12 *                                                                           *
     13 *         email: markb@epcc.ed.ac.uk or fiona@epcc.ed.ac.uk                 *
     14 *                                                                           *
     15 *                                                                           *
     16 *      This version copyright (c) The University of Edinburgh, 2015.        *
     17 *                                                                           *
     18 *                                                                           *
     19 *  Licensed under the Apache License, Version 2.0 (the "License");          *
     20 *  you may not use this file except in compliance with the License.         *
     21 *  You may obtain a copy of the License at                                  *
     22 *                                                                           *
     23 *      http://www.apache.org/licenses/LICENSE-2.0                           *
     24 *                                                                           *
     25 *  Unless required by applicable law or agreed to in writing, software      *
     26 *  distributed under the License is distributed on an "AS IS" BASIS,        *
     27 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
     28 *  See the License for the specific language governing permissions and      *
     29 *  limitations under the License.                                           *
     30 *                                                                           *
     31 ****************************************************************************/
     32 
     33 #include <stdio.h>
     34 #include <stdlib.h>
     35 #include <omp.h>
     36 
     37 #include "common.h"
     38 #include "taskbench.h"
     39 
     40 #define DEPTH 6
     41 
     42 int main(int argc, char **argv) {
     43 
     44     init(argc, argv);
     45 
     46 #ifdef OMPVER3
     47 
     48     /* GENERATE REFERENCE TIME */
     49     reference("reference time 1", &refer);
     50 
     51     /* TEST PARALLEL TASK GENERATION */
     52     benchmark("PARALLEL TASK", &testParallelTaskGeneration);
     53 
     54     /* TEST MASTER TASK GENERATION */
     55     benchmark("MASTER TASK", &testMasterTaskGeneration);
     56 
     57     /* TEST MASTER TASK GENERATION WITH BUSY SLAVES */
     58     benchmark("MASTER TASK BUSY SLAVES", &testMasterTaskGenerationWithBusySlaves);
     59 
     60     /* TEST CONDITIONAL TASK GENERATION */
     61 #ifndef DISABLE_CONDITIONAL_TASK_TEST
     62     benchmark("CONDITIONAL TASK", &testConditionalTaskGeneration);
     63 #endif // DISABLE_CONDITIONAL_TASK_TEST
     64 
     65     /* TEST TASK WAIT */
     66     benchmark("TASK WAIT", &testTaskWait);
     67 
     68     /* TEST TASK BARRIER */
     69 #ifndef DISABLE_BARRIER_TEST
     70     benchmark("TASK BARRIER", &testTaskBarrier);
     71 #endif //DISABLE_BARRIER_TEST
     72 
     73 #ifndef DISABLE_NESTED_TASKS_TESTS
     74     /* TEST NESTED TASK GENERATION */
     75     benchmark("NESTED TASK", &testNestedTaskGeneration);
     76 
     77     /* TEST NESTED MASTER TASK GENERATION */
     78     benchmark("NESTED MASTER TASK", &testNestedMasterTaskGeneration);
     79 
     80 #endif // DISABLE_NESTED_TASKS_TESTS
     81 
     82     /* GENERATE THE SECOND REFERENCE TIME */
     83     reference("reference time 2", &refer);
     84 
     85     /* TEST BRANCH TASK TREE */
     86     benchmark("BRANCH TASK TREE", &testBranchTaskGeneration);
     87 
     88     /* TEST LEAF TASK TREE */
     89     benchmark("LEAF TASK TREE", &testLeafTaskGeneration);
     90 
     91 #endif // OMPVER3
     92 
     93     finalise();
     94 
     95     return EXIT_SUCCESS;
     96 
     97 }
     98 
     99 /* Calculate the reference time. */
    100 void refer() {
    101     int j;
    102     for (j = 0; j < innerreps; j++) {
    103 	delay(delaylength);
    104     }
    105 
    106 }
    107 
    108 /* Calculate the second reference time. */
    109 void refer2() {
    110     int j;
    111     for (j = 0; j < (innerreps >> DEPTH) * (1 << DEPTH); j++) {
    112 	delay(delaylength);
    113     };
    114 
    115 }
    116 
    117 /* Test parallel task generation overhead */
    118 void testParallelTaskGeneration() {
    119     int j;
    120 #pragma omp parallel private( j )
    121     {
    122 	for ( j = 0; j < innerreps; j ++ ) {
    123 #pragma omp task
    124 	    {
    125 		delay( delaylength );
    126 
    127 	    } // task
    128 	}; // for j
    129     } // parallel
    130 
    131 }
    132 
    133 /* Test master task generation overhead */
    134 void testMasterTaskGeneration() {
    135     int j;
    136 #pragma omp parallel private(j)
    137     {
    138 #pragma omp master
    139 	{
    140 	    /* Since this is executed by one thread we need innerreps * nthreads
    141 	       iterations */
    142 	    for (j = 0; j < innerreps * nthreads; j++) {
    143 #pragma omp task
    144 		{
    145 		    delay(delaylength);
    146 
    147 		}
    148 
    149 	    } /* End for j */
    150 	} /* End master */
    151     } /* End parallel */
    152 
    153 }
    154 
    155 /* Test master task generation overhead when the slave threads are busy */
    156 void testMasterTaskGenerationWithBusySlaves() {
    157     int j;
    158 #pragma omp parallel private( j )
    159     {
    160 	int thread_num = omp_get_thread_num();
    161 	for (j = 0; j < innerreps; j ++ ) {
    162 
    163 	    if ( thread_num == 0 ) {
    164 #pragma omp task
    165 		{
    166 		    delay( delaylength );
    167 		} // task
    168 
    169 	    } else {
    170 		delay( delaylength );
    171 
    172 	    }; // if
    173 	}; // for j
    174     } // parallel
    175 }
    176 
    177 /* Measure overhead of checking if a task should be spawned. */
    178 void testConditionalTaskGeneration() {
    179     int j;
    180 #pragma omp parallel private(j)
    181     {
    182 	for (j = 0; j < innerreps; j++) {
    183 #pragma omp task if(returnfalse())
    184 	    {
    185 		delay( delaylength );
    186 	    }
    187 	}
    188     }
    189 }
    190 
    191 #ifndef DISABLE_NESTED_TASKS_TESTS
    192 
    193 /* Measure overhead of nested tasks (all threads construct outer tasks) */
    194 void testNestedTaskGeneration() {
    195     int i,j;
    196 #pragma omp parallel private( i, j )
    197     {
    198 	for ( j = 0; j < innerreps / nthreads; j ++ ) {
    199 #pragma omp task private( i )
    200 	    {
    201 		for ( i = 0; i < nthreads; i ++ ) {
    202 #pragma omp task untied
    203 		    {
    204 			delay( delaylength );
    205 
    206 		    } // task
    207 		}; // for i
    208 
    209 		// wait for inner tasks to complete
    210 #pragma omp taskwait
    211 
    212 	    } // task
    213 	}; // for j
    214     } // parallel
    215 }
    216 
    217 /* Measure overhead of nested tasks (master thread constructs outer tasks) */
    218 void testNestedMasterTaskGeneration() {
    219     int i, j;
    220 #pragma omp parallel private( i, j )
    221     {
    222 #pragma omp master
    223 	{
    224 	    for ( j = 0; j < innerreps; j ++ ) {
    225 #pragma omp task private( i )
    226 		{
    227 		    for ( i = 0; i < nthreads; i ++ ) {
    228 #pragma omp task
    229 			{
    230 			    delay( delaylength );
    231 
    232 			} // task
    233 		    }; // for i
    234 
    235 		    // wait for inner tasks to complete
    236 #pragma omp taskwait
    237 
    238 		} // task
    239 	    }; // for j
    240 	} // master
    241     } // parallel
    242 }
    243 #endif // DISABLE_NESTED_TASKS_TESTS
    244 
    245 /* Measure overhead of taskwait (all threads construct tasks) */
    246 void testTaskWait() {
    247     int j;
    248 #pragma omp parallel private( j )
    249     {
    250 	for ( j = 0; j < innerreps; j ++ ) {
    251 #pragma omp task
    252 	    {
    253 		delay( delaylength );
    254 
    255 	    } // task
    256 #pragma omp taskwait
    257 
    258 	}; // for j
    259     } // parallel
    260 }
    261 
    262 /* Measure overhead of tasking barrier (all threads construct tasks) */
    263 void testTaskBarrier() {
    264     int j;
    265 #pragma omp parallel private( j )
    266     {
    267 	for ( j = 0; j < innerreps; j ++ ) {
    268 #pragma omp task
    269 	    {
    270 		delay( delaylength );
    271 
    272 	    } // task
    273 #pragma omp barrier
    274 
    275 	}; // for j
    276     } // parallel
    277 }
    278 
    279 /* Test parallel task generation overhead where work is done at all levels. */
    280 void testBranchTaskGeneration() {
    281     int j;
    282 #pragma omp parallel private(j)
    283     {
    284 	for (j = 0; j < (innerreps >> DEPTH); j++) {
    285 #pragma omp task
    286 	    {
    287 		branchTaskTree(DEPTH);
    288 		delay(delaylength);
    289 	    }
    290 
    291 	}
    292     }
    293 }
    294 
    295 void branchTaskTree(int tree_level) {
    296     if ( tree_level > 0 ) {
    297 #pragma omp task
    298 	{
    299 	    branchTaskTree(tree_level - 1);
    300 	    branchTaskTree(tree_level - 1);
    301 	    delay(delaylength);
    302 	}
    303     }
    304 }
    305 
    306 /* Test parallel task generation overhead where work is done only at the leaf level. */
    307 void testLeafTaskGeneration() {
    308     int j;
    309 #pragma omp parallel private(j)
    310     {
    311 	for (j = 0; j < (innerreps >> DEPTH); j++) {
    312 	    leafTaskTree(DEPTH);
    313 
    314 	}
    315     }
    316 
    317 }
    318 
    319 void leafTaskTree(int tree_level) {
    320     if ( tree_level == 0 ) {
    321 	delay(delaylength);
    322 
    323     } else {
    324 #pragma omp task
    325 	{
    326 	    leafTaskTree(tree_level - 1);
    327 	    leafTaskTree(tree_level - 1);
    328 	}
    329     }
    330 }
    331