#include #include #include #include #include #include #include #include #include #include #include "rib_core.h" #include "rib.h" #include "config.h" #include "benchmark.h" #include #include #include #include #ifdef ENABLE_PAPI #include #endif using namespace std; static bool print_times = false; static bool force = false; static Benchmark * bench = NULL; static ThrashingBenchmark * thrash = NULL; static long cps; static unsigned int warmup_count; static unsigned int samples_count; static clock_t startup_time; static size_t rib_run; static fstream rib_runs; size_t get_rib_run() { return rib_run; } string get_rib_result_name() { return bench->result_filename() + "-" + thrash->result_filename(); } void rib_init(int argc, char ** argv) { if ((argc == 2) && (strcmp(argv[1], "-t") == 0)) { print_times = true; } else { print_times= false; } if ((argc == 2) && (strcmp(argv[1], "-f") == 0)) { force = true; } else { force = false; } cps = sysconf(_SC_CLK_TCK); struct tms tm; startup_time = times(&tm); cout << "Clocks per sec: " << cps << endl; srandom(rdtsc()); } #ifdef ENABLE_PAPI static void rib_papi_init() { int r = PAPI_library_init(PAPI_VER_CURRENT); if (r != PAPI_VER_CURRENT && r > 0) { cerr << "PAPI library version mismatch!" << endl; exit(EXIT_FAILURE); } if (r < 0) { cerr << "PAPI initialization error: " << PAPI_strerror(r) << endl; exit(EXIT_FAILURE); } cout << "PAPI version: " << PAPI_VERSION_MAJOR(r) << "." << PAPI_VERSION_MINOR(r) << "." << PAPI_VERSION_REVISION(r) << endl; cout << "HW counters: " << PAPI_num_hwctrs() << endl; if ((r = PAPI_set_domain(PAPI_DOM_ALL)) != PAPI_OK) { cerr << "PAPI_set_domain: " << PAPI_strerror(r) << endl; exit(EXIT_FAILURE); } } #endif /* ENABLE_PAPI */ void rib_read_ini() { map > allparams = parse_ini("rib.ini"); if (allparams.find("benchmark") == allparams.end()) { cerr << "missing [benchmark] section in rib.ini" << endl; exit(EXIT_FAILURE); } // if (allparams.find("thrashing") == allparams.end()) { // cerr << "missing [thrashing] section in rib.ini" << endl; // exit(EXIT_FAILURE); // } map params = allparams.find("global")->second; if (params.find("benchmark") == params.end()) { cerr << "missing benchmark parameter in rib.ini" << endl; exit(EXIT_FAILURE); } if (params.find("thrashing") == params.end()) { cerr << "missing thrashing parameter in rib.ini" << endl; exit(EXIT_FAILURE); } if (params.find("warmup_count") == params.end()) { cerr << "missing warmup_count parameter in rib.ini" << endl; exit(EXIT_FAILURE); } if (params.find("samples_count") == params.end()) { cerr << "missing samples_count parameter in rib.ini" << endl; exit(EXIT_FAILURE); } warmup_count = ((BenchParameterNumeric *)(*params["warmup_count"].begin()))->begin; samples_count = ((BenchParameterNumeric *)(*params["samples_count"].begin()))->begin; #ifdef ENABLE_PAPI // new parameter, defaults to 1 int use_papi = 1; if (params.find("papi") != params.end()) { use_papi = ((BenchParameterNumeric *)(*params["papi"].begin()))->begin; } if (use_papi) { rib_papi_init(); } #else int use_papi = 0; #endif /* ENABLE_PAPI */ cout << "Benchmarking: " << ((BenchParameterString*)(*params["benchmark"].begin()))->value << endl; bench = Benchmark::CreateBenchmark(((BenchParameterString*)(*params["benchmark"].begin()))->value); if (!bench) { cerr << "no valid benchmark specified" << endl; exit(1); } bench->initialize_params(allparams.find("benchmark")->second, false, use_papi); cout << "Thrashing with: " << ((BenchParameterString*)(*params["thrashing"].begin()))->value << endl; thrash = ThrashingBenchmark::CreateThrashingBenchmark(((BenchParameterString*)(*params["thrashing"].begin()))->value); if (!thrash) { cerr << "no valid thrasher specified" << endl; exit(1); } if (allparams.find("thrashing") != allparams.end()) { thrash->initialize_params(allparams.find("thrashing")->second, false, use_papi); } map > resume_params = parse_ini("rib.resume"); map >::iterator rp; if ((rp = resume_params.find("benchmark")) != resume_params.end()) { bench->params.resume(rp->second); } if ((rp = resume_params.find("thrashing")) != resume_params.end()) { thrash->params.resume(rp->second); } mkdir("results", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); rib_runs.open("rib.runs", ios::in); rib_runs >> rib_run; if (rib_runs.fail()) { rib_run = 1; } else { ++rib_run; } rib_runs.close(); rib_runs.clear(); cout << "Run number: " << rib_run << endl; cout << "Samples per run: " << samples_count << endl; cout << "Warmups per sample: " << warmup_count << endl; free_ini(allparams); } int rib_run_standard() { struct tms tm; ofstream result; bool running = true; while (running && bench->nextRun()) while (thrash->nextRun()) { int result_cols_num = bench->result_cols_num() + thrash->result_cols_num(); int result_rows_num = max(bench->result_rows_num(), thrash->result_rows_num()); // cout << samples_count * result_cols_num * result_rows_num; tsc_t * samples = new tsc_t[samples_count * result_cols_num * result_rows_num]; clock_t real = times(&tm); clock_t user = tm.tms_utime; clock_t system = tm.tms_stime; std::string result_name("results/"); bench->result_filename(); result_name += bench->result_filename() + "-" + thrash->result_filename(); cout << result_name << endl; cout << "[benchmark]" << endl; bench->params.printNamesValues(cout, ": ", true); cout << "[thrashing]" << endl; thrash->params.printNamesValues(cout, ": ", true); bench->benchmark(warmup_count, samples_count, thrash, samples); result.open(result_name.c_str(), ios::app); if (!result) { cerr << "Error opening result"; exit(EXIT_FAILURE); } if ((int) result.tellp() == (int) 0) { result << "run\tsample\t"; bench->print_result_cols_header(result, ""); result << "\t"; thrash->print_result_cols_header(result, "T_"); result << endl; } for (unsigned int i = 0; i < samples_count; i++) { for (int k = 0; k < result_rows_num; k++) { result << rib_run << "\t" << i+1 << "\t"; for (int j = 0; j < bench->result_cols_num(); j++) { result << samples[i*(result_cols_num*result_rows_num) + k*result_cols_num + j] << "\t"; } // bench->print_param_values(result, "\t"); result << "\t"; for (int j = 0; j < thrash->result_cols_num(); j++) { result << samples[i*(result_cols_num*result_rows_num) + k*result_cols_num + bench->result_cols_num() + j] << "\t"; } // thrash->print_param_values(result, "\t"); result << endl; } } result.close(); delete[] samples; clock_t end_time = times(&tm); if (print_times) { cout << "Real time: " << float(end_time - real) / cps << "s" << endl; cout << "User time: " << float(tm.tms_utime - user) / cps << "s" << endl; cout << "System time: " << float(tm.tms_stime - system) / cps << "s" << endl; } if (!force && ((end_time - startup_time) / cps) >= 3) { cout << "Time slice exhausted" << endl; if (thrash->nextRun() || (bench->nextRun() && (thrash->params.resetAll(), true))) { return RIB_TIME_EXHAUSTED; } else { running = 0; break; } } } return RIB_SUCCESS; } void rib_write_resume() { cout << "Writing resume info" << endl; ofstream rib_resume("rib.resume"); rib_resume << "[benchmark]" << endl; bench->params.printNamesValues(rib_resume, "=", false); rib_resume << "[thrashing]" << endl; thrash->params.printNamesValues(rib_resume, "=", false); rib_resume.close(); } void rib_update_samples_runs() { fstream rib_samples("rib.samples", ios::in); size_t samples_total; rib_samples >> samples_total; if (rib_samples.fail()) { samples_total = 0; } samples_total += samples_count; rib_samples.close(); rib_samples.clear(); rib_samples.open("rib.samples", ios::out); rib_samples << samples_total << endl; rib_samples.close(); rib_runs.open("rib.runs", ios::out); rib_runs << rib_run << endl; rib_runs.close(); unlink("rib.resume"); } void rib_close() { if (bench) delete bench; if (thrash) delete thrash; bench = thrash = NULL; }