/* * Copyright (C) 2011 Thomas Preud'homme * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include #include #include #define TIMEINF(t1, t2) ((t1.tv_sec < t2.tv_sec) || (t1.tv_usec < t2.tv_usec)) #define STRTOL_OVERFLOW(n) (((n == LONG_MIN) || (n == LONG_MAX)) && \ (errno == ERANGE)) long busy_usecs = 42; long total_time_usecs = 42; unsigned int seed; void node(long entry_input, long *entry_output) { //struct timeval cur_time, end_time; //long long usecs; long entry; static long inc = 0; entry = entry_input + inc++; /*gettimeofday(&cur_time, 0); usecs = busy_usecs + cur_time.tv_usec + cur_time.tv_sec * 1000000; end_time.tv_usec = usecs % 1000000; end_time.tv_sec = usecs / 1000000; while (TIMEINF(cur_time, end_time)) gettimeofday(&cur_time, 0);*/ *entry_output = entry; } int main(int argc, char *argv[]) { unsigned int i, j, seed; char **arg_p; long entries_1[8], entries_2[8], entries_3[8], entries_4[8], entries_5[8], entries_6[8]; //long entries_7[8], entries_8[8], entries_9[8], entries_10[8]; long entries_input[8], entries_output[8]; long nb_entries, result; argc--; arg_p = argv; while(arg_p++, argc--) { if ((*arg_p)[0] == '-') { if ((!(*arg_p)[1]) || (*arg_p)[2]) { printf("Unsupported option: %s\n", *arg_p); return -1; } switch((*arg_p)[1]) { char *endptr; case 't': argc--, arg_p++; busy_usecs = strtol(*arg_p, &endptr, 10); if ((endptr == *arg_p) || (STRTOL_OVERFLOW(busy_usecs))) { fprintf(stderr, "Invalid time: " "%s\n", *arg_p); return -1; } break; case 'T': argc--, arg_p++; total_time_usecs = strtol(*arg_p, &endptr, 10); if ((endptr == *arg_p) || (STRTOL_OVERFLOW(total_time_usecs))) { fprintf(stderr, "Invalid time: " "%s\n", *arg_p); return -1; } break; default: printf("Unsupported option: %s\n", *arg_p); return -1; } } } nb_entries = total_time_usecs / busy_usecs; printf("total_time_usecs: %ld, busy_usecs: %ld, nb_entries: %ld\n", total_time_usecs, busy_usecs, nb_entries); seed = 42; result = 0; #pragma omp parallel num_threads (1) default (none) \ shared (nb_entries, entries_output, seed, result) \ private (entries_input, entries_1, entries_2, entries_3, entries_4, entries_5, entries_6, i, j) //private (entries_input, entries_1, entries_2, entries_3, entries_4, entries_5, entries_6, entries_7, entries_8, entries_9, entries_10, i, j) { #pragma omp single { long random = rand_r(&seed); long inc; inc = random; for (i = 0; i < nb_entries; i += 64 / sizeof(long)) { #pragma omp task output (entries_input) shared (inc) private (j) { for (j = 0; j < 64 / sizeof(long); j++) entries_input[j] = inc++; } #pragma omp task input (entries_input) output (entries_1) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_input[j], &entries_1[j]); #pragma omp task input (entries_1) output (entries_2) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_1[j], &entries_2[j]); #pragma omp task input (entries_2) output (entries_3) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_2[j], &entries_3[j]); #pragma omp task input (entries_3) output (entries_4) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_3[j], &entries_4[j]); #pragma omp task input (entries_4) output (entries_5) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_4[j], &entries_5[j]); #pragma omp task input (entries_5) output (entries_6) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_5[j], &entries_6[j]); #if 0 #pragma omp task input (entries_6) output (entries_7) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_6[j], &entries_7[j]); #pragma omp task input (entries_7) output (entries_8) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_7[j], &entries_8[j]); #pragma omp task input (entries_8) output (entries_9) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_8[j], &entries_9[j]); #pragma omp task input (entries_9) output (entries_10) private (j) for (j = 0; j < 64 / sizeof(long); j++) node(entries_9[j], &entries_10[j]); #endif #pragma omp task input (entries_6) shared (result, entries_output) private (j) for (j = 0; j < 64 / sizeof(long); j++) { node(entries_6[j], &entries_output[j]); result += entries_output[j]; } } } } printf("result: %ld\n", result); return 0; }