/** * Retrace one call. * * Take snapshots before/after retracing (as appropriate) and dispatch it to * the respective handler. */ static void retraceCall(trace::Call *call) { bool swapRenderTarget = call->flags & trace::CALL_FLAG_SWAP_RENDERTARGET; bool doSnapshot = snapshotFrequency.contains(*call); // For calls which cause rendertargets to be swaped, we take the // snapshot _before_ swapping the rendertargets. if (doSnapshot && swapRenderTarget) { if (call->flags & trace::CALL_FLAG_END_FRAME) { // For swapbuffers/presents we still use this // call number, spite not have been executed yet. takeSnapshot(call->no); } else { // Whereas for ordinate fbo/rendertarget changes we // use the previous call's number. takeSnapshot(call->no - 1); } } callNo = call->no; calcStatistics(*call); retracer.retrace(*call); if (doSnapshot && !swapRenderTarget) takeSnapshot(call->no); if (call->no >= dumpStateCallNo && dumper->dumpState(std::cout)) { exit(0); } }
int main(int argc, char **argv) { /* limits */ int niter = 1; int nscambi = 100000; /* threads */ int cpu_white, cpu_black, cpu_main; int white_rank = 0, black_rank = 61; void * ch[2]; /* statistics */ struct timeval start; struct timeval end; /* 0 current, 1 sum, 2 square sum, 3 max value */ uint64_t result_test[4] = { 0, 0, 0, 0 }; double elapsed_test[4] = { 0, 0, 0, 0 }; double avg_Tscambio[4] = { 0 }; double sdev_Tscambio[4] = { 0 }; double max_Tscambio[4] = { 0 }; /* 0 results, 1 elapsed_test, 2 Tscambio, 3 avg_Tscambio, 4 sdev_Tscambio, 5 max_Tscambio */ double avg[6]; double sdev[6]; /* others */ cpu_set_t dp, udn_hardwall; int i; int retval[2]; int opt; int longopt; struct option options[] = { { "niter", required_argument, &longopt, 'n' }, { "nscambi",required_argument, &longopt, 'm' }, { "white", required_argument, &longopt, 'w' }, { "black", required_argument, &longopt, 'b' }, { NULL, 0, NULL, 0 } }; while (longopt || -1 != (opt = getopt_long(argc, argv, "n:m:w:b:", options, NULL))) { switch (opt) { case 'n': niter = atoi(optarg); break; case 'w': white_rank = atoi(optarg); break; case 'b': black_rank = atoi(optarg); break; case 'm': nscambi = atoi(optarg); break; case 0: opt=longopt; continue; } longopt =0; } signal(SIGALRM, sighand_alrm); /* defines cpus */ ERRHAND(tmc_cpus_get_dataplane_cpus(&dp)); if (tmc_cpus_count(&dp) < 3) fprintf(stderr, "[ERROR] numero di cpu dataplane disponibili non sufficiente\n"); //ERRHAND(cpu_white = tmc_cpus_find_first_cpu(&dp)); //ERRHAND(cpu_black = tmc_cpus_find_last_cpu(&dp)); ERRHAND(cpu_white = tmc_cpus_find_nth_cpu(&dp, white_rank)); ERRHAND(cpu_black = tmc_cpus_find_nth_cpu(&dp, black_rank)); ERRHAND(cpu_main = tmc_cpus_find_nth_cpu(&dp, tmc_cpus_count(&dp)-2)); /* bind this process to a dataplane cpu */ ERRHAND(tmc_cpus_set_my_cpu(cpu_main)); #if TEST_VERBOSE >= 1 printf("[INFO] main: cpu %d niter %d\n", tmc_cpus_get_my_cpu(), niter); #endif printf("main on cpu %d, white on cpu %d, black on cpu %d, " "num of test iteration %d, num of exchanges %d\n", tmc_cpus_get_my_cpu(), cpu_white, cpu_black, niter, nscambi); /* define ansd initialize udn hardwall */ tmc_cpus_clear(&udn_hardwall); ERRHAND(tmc_cpus_add_cpu(&udn_hardwall, cpu_main)); ERRHAND(tmc_cpus_add_cpu(&udn_hardwall, cpu_white)); ERRHAND(tmc_cpus_add_cpu(&udn_hardwall, cpu_black)); ERRHAND(tmc_udn_init(&dp)); /* init synchronization barriers */ ERRHAND_NZ(pthread_barrier_init(&computation_start, NULL, 2)); ERRHAND_NZ(pthread_barrier_init(&computation_end, NULL, 2)); for (i=0; i<niter; i++) { arg_t arg[2]; Tscambio[1] = 0; Tscambio[2] = 0; Tscambio[3] = 0; /* START TEST i-esimo */ ERRHAND(gettimeofday(&start, NULL)); /* set deadlock alarm */ alarm(deadlock_timeout); /* setup environment */ ERRHAND_NN(ch[0] = ch_create(CH0_IMPL)(cpu_white, cpu_black CH0_CREATE_ARGS)); ERRHAND_NN(ch[1] = ch_create(CH1_IMPL)(cpu_black, cpu_white CH1_CREATE_ARGS)); arg[0].cpu = cpu_white; arg[0].ch[0] = ch[0]; arg[0].ch[1] = ch[1]; arg[0].num_scambi = nscambi; arg[1].cpu = cpu_black; arg[1].ch[0] = ch[0]; arg[1].ch[1] = ch[1]; arg[1].num_scambi = nscambi; /* start computation */ ERRHAND_NZ(pthread_create(&thread_white, NULL, task_pingpong_white, (void *)&arg[0])); ERRHAND_NZ(pthread_create(&thread_black, NULL, task_pingpong_black, (void *)&arg[1])); /* wait end of computation */ ERRHAND_NZ(pthread_join(thread_white, (void *)retval)); ERRHAND_NZ(pthread_join(thread_black, (void *)(retval+1))); /* destroy environment */ ch_destroy(CH0_IMPL)(ch); ch_destroy(CH1_IMPL)(ch+1); /* END TEST i-esimo */ ERRHAND(gettimeofday(&end, NULL)); /* statistiche sugli scambi eseguiti nel test corrente */ calcStatistics(avg[2], sdev[2], Tscambio, nscambi); timersub(&end, &start, &start); prepareStatistics(elapsed_test, start.tv_sec*1000+start.tv_usec/(double)1000); prepareStatistics(result_test, retval[0] + retval[1]); prepareStatistics(avg_Tscambio, avg[2]); prepareStatistics(sdev_Tscambio, sdev[2]); prepareStatistics(max_Tscambio, Tscambio[3]); #if TEST_VERBOSE == 0 //fprintf(stderr, "%d:%f:%f:%f:(%f);", i, avg[2]/2, sdev[2], (double)Tscambio[3]/2, avg_Tscambio[2]); #elif TEST_VERBOSE >= 2 fprintf(stderr, printStatistics_format("Tscambio (cycles)", PRIu64) "[STAT] Tsend (cycles):\n[STAT] %f\n", printStatistics_values(avg[2], sdev[2], Tscambio), avg[2]/(double)2 ); #endif /* TEST_VERBOSE == 0 */ deadlock_continue = 0; } /* for (i=0; i<niter; i++) */ calcStatistics(avg[0], sdev[0], result_test, niter); calcStatistics(avg[1], sdev[1], elapsed_test, niter); calcStatistics(avg[3], sdev[3], avg_Tscambio, niter); calcStatistics(avg[4], sdev[4], sdev_Tscambio, niter); calcStatistics(avg[5], sdev[5], max_Tscambio, niter); /* fprintf(stderr, printStatistics_format("Tscambio avg (cycles)", "f") printStatistics_format("Tscambio sdev (cycles)", "f") "[STAT] Tscambio max (cycles):\n[STAT] %f\n", printStatistics_values(avg[3], sdev[3], avg_Tscambio), printStatistics_values(avg[4], sdev[4], sdev_Tscambio), maxmax_Tscambio ); */ /* fprintf(stderr, printStatistics_format2("Tscambio avg (cycles)", "f") printStatistics_format2("Tscambio sdev ", "f") printStatistics_format2("Tscambio max (cycles)", "f"), printStatistics_values2(avg[3], sdev[3], avg_Tscambio), printStatistics_values2(avg[4], sdev[4], sdev_Tscambio), printStatistics_values2(avg[5], sdev[5], max_Tscambio) ); Tscambio avg (cycles): 110.491957 0.258812 111.400840 Tscambio sdev : 118.790573 63.409627 306.372066 Tscambio max (cycles): 34756.240000 18675.977854 80419.000000 */ fprintf(stderr, "%-20s %-20s %-20s\n" "%-20f %-20f %-20f\n", "avg", "sdev", "max", avg[3], avg[4], avg[5]); fprintf(stderr, "\n\n" " %-20s %-20s %-20s\n" "Tscambio-avg: %-20f %-20f %-20f\n" "Tscambio-dev: %-20f %-20f %-20f\n" "Tscambio-max: %-20f %-20f %-20f\n", "avg", "sdev", "max", avg[3], avg[4], avg[5], sdev[3], sdev[4], sdev[5], avg_Tscambio[3], sdev_Tscambio[3], max_Tscambio[3] ); #if TEST_VERBOSE == 0 #else #endif /* TEST_VERBOSE == 0 */ return 0; }
int main(int argc, char **argv) { cpu_set_t dp; int retval[2]; if (argc > 1) niter = atoi(argv[1]); signal(SIGALRM, sighand_alrm); ERRHAND(tmc_cpus_get_dataplane_cpus(&dp)); ERRHAND(cpu_snd = tmc_cpus_find_first_cpu(&dp)); ERRHAND(cpu_rcv = tmc_cpus_find_last_cpu(&dp)); ERRHAND_NZ(pthread_barrier_init(&computation_end, NULL, 2)); for (cur_suite=0; cur_suite<niter; cur_suite++) { PRINT(fprintf(stderr, "[INFO] start test suite %d\n", cur_suite)); /* --> init shared objects */ ERRHAND_NN(ch = ch_sym_ref_sm_create(M, cpu_snd, cpu_rcv, NULL)); /* set deadlock alarm */ alarm(deadlock_timeout); /* start */ ERRHAND(gettimeofday(&start, NULL)); ERRHAND_NZ (pthread_create(&thread_producer, NULL, task_producer, (void *)cpu_snd)); ERRHAND_NZ (pthread_create(&thread_consumer, NULL, task_consumer, (void *)cpu_rcv)); /* wait end */ ERRHAND_NZ(pthread_join(thread_producer, (void *)retval)); ERRHAND_NZ(pthread_join(thread_consumer, (void *)(retval+1))); /* end */ ERRHAND(gettimeofday(&end, NULL)); timersub(&end, &start, &start); prepareStatistics(time_suite, start.tv_sec*1000+start.tv_usec/(double)1000); prepareStatistics(result_suite, retval[0] + retval[1]); PRINT(fprintf(stderr, "[INFO] end test suite %d: producer %d consumer %d\n", cur_suite, retval[0], retval[1])); /* --> destroy shared object */ ch_sym_ref_sm_destroy(&ch); deadlock_continue = 0; } calcStatistics(avg[0], sdev[0], result_suite, niter); calcStatistics(avg[1], sdev[1], time_suite, niter); printf(printStatistics_format("return values", PRIu64) printStatistics_format("elapsed time", "f") printStatistics_format("Tcall-send", PRIu64) printStatistics_format("Tcall-recv", PRIu64) printStatistics_format("Tsend", PRIu64), printStatistics_values(avg[0], sdev[0], result_suite), printStatistics_values(avg[1], sdev[1], time_suite), printStatistics_values(avg[2], sdev[2], call_send), printStatistics_values(avg[3], sdev[3], call_recv), printStatistics_values(avg[4], sdev[4], send) ); return result_suite[1]; }