int main(int argc, char *argv[]) { int loops = 100, inner_loops = 100; int smin = 0, smax = 100000, sstep = 5000; int *values[] = { &loops, &smin, &smin, &smax, &smax, &sstep, &sstep }; const char *identifier[] = { "-l", "-smin", "-rmin", "-smax", "-rmax", "-sstep", "-rstep" }; handle_args(argc, argv, 7, values, identifier); printf("Loops: %d\n", loops); printf("Sizes: %d - %d, steps of %d\n", smin, smax, sstep); printf("Size;Expected Value;Standard deviation\n"); for (int size = smin; size <= smax; size += sstep) { printf("%d", size); Stats stats; for (int l = 0; l < loops; l++) { int failures = 0; for (int il = 0; il < inner_loops; il++) { // init unsigned char a[size]; for (int i = 0; i < size; i++) a[i] = 0; // run int flip = 0; // alternates between 0 (read) and 1 (write) int dummy; if (_xbegin() == _XBEGIN_STARTED) { for (int i = 0; i < size; i++) { if (flip) dummy = a[i]; // -O0! else a[i]++; flip ^= 1; } _xend(); } else { failures++; } } float failure_rate = (float) failures * 100 / inner_loops; stats.addValue(failure_rate); } printf(";%.2f;%.2f\n", stats.getExpectedValue(), stats.getStandardDeviation()); } }
int main(int argc, char *argv[]) { int num_threads = 4; int loops = 10; int lockFunction = 0; int partitioned = 0, duration = 10000, warmup = duration / 10; int *values[] = { &num_threads, &loops, &partitioned, &lockFunction, &sleep_time, &pin, &duration, &warmup }; const char *identifier[] = { "-n", "-l", "-partition", "-t", "-sleep", "-pin", "-d", "-w" }; handle_args(argc, argv, 9, values, identifier); printf("Threads: %d\n", num_threads); printf("sizeof(type): %lu | padded: %lu\n", sizeof(((mutex_type *) 0)->value), sizeof(mutex_type)); printf("Loops: %d\n", loops); printf("Partitioned: %s\n", partitioned ? "yes" : "no"); printf("Pinned: %s\n", pin ? "yes" : "no"); printf("sleep: %d\n", sleep_time); printf("Duration: %d microseconds (%d microseconds warmup)\n", duration, warmup); int sizes[] = { 10 }; //{ 1, 10, 100 }; //{ 1000, 5500, 10000 }; // {10, 55, 100}; // int lockFunctionsMin, lockFunctionsMax; switch (lockFunction) { case -1: case 2: case 3: lockFunctionsMin = 0; lockFunctionsMax = LOCK_FUNCTIONS_LENGTH; break; default: lockFunctionsMin = lockFunction; lockFunctionsMax = lockFunction + 1; break; } // init int lock_accesses_size = 1000000; pthread_t threads[num_threads]; printHeader(lockFunction); for (int s = 0; s < sizeof(sizes) / sizeof(sizes[0]); s++) { int mutexes_array_size = sizes[s]; printf("%d", mutexes_array_size); std::cout.flush(); mutexes = (mutex_type *) calloc( sizes[sizeof(sizes) / sizeof(sizes[0]) - 1], // always allocate maximum amount sizeof(mutex_type)); // loop over functions, loops, threads for (int f = lockFunctionsMin; f < lockFunctionsMax; f++) { Stats stats; for (int l = 0; l < loops; l++) { // create random access values for each thread int ** lock_accesses = new int*[num_threads]; for (int t = 0; t < num_threads; t++) { lock_accesses[t] = new int[lock_accesses_size]; // partitioned int partition_left, partition_size; if (partitioned) { partition_size = mutexes_array_size / num_threads; partition_left = t * partition_size; } for (int a = 0; a < lock_accesses_size; a++) { if (partitioned) { lock_accesses[t][a] = partition_left + (rand() % partition_size); // printf("lock_accesses[%d][%d] = %d\n", t, a, lock_accesses[t][a]); } else { // shared lock_accesses[t][a] = rand() % mutexes_array_size; } } } // measure operations_count = new int[num_threads]; stop_run = 0; // BEGIN: run std::thread threads[num_threads]; for (int t = 0; t < num_threads; t++) { threads[t] = std::thread(run, t, lock_functions[f], unlock_function, lock_accesses[t], lock_accesses_size); } // end threads loop // warmup usleep(warmup); for (int i = 0; i < num_threads; i++) { operations_count[i] = 0; // reset } usleep(duration); stop_run = 1; // stop runs for (int i = 0; i < num_threads; i++) { threads[i].join(); // make sure result has been written } int total_operations = 0; for (int i = 0; i < num_threads; i++) { total_operations += operations_count[i]; } // measure time int time_in_millis = duration / 1000; float throughput_total = ((float) total_operations) / time_in_millis; stats.addValue(throughput_total); // clean up delete[] operations_count; for (int t = 0; t < num_threads; t++) { delete[] lock_accesses[t]; } // TODO corruption error (double free) for uchar size 1000 and ushort size 100 } printf(";%.2f;%.2f", stats.getExpectedValue(), stats.getStandardDeviation()); std::cout.flush(); } // end lock functions loop printf("\n"); free(mutexes); } }
int main(int argc, char *argv[]) { // arguments int loops = 10, sizes_min = 1, sizes_max = 1000000, sizes_step = 5000, write = 0; int *values[] = { &loops, &sizes_min, &sizes_min, &sizes_max, &sizes_max, &sizes_step, &sizes_step, &write, &max_retries }; const char *identifier[] = { "-l", "-smin", "-rmin", "-smax", "-rmax", "-sstep", "-rstep", "-w", "-max_retries" }; handle_args(argc, argv, 9, values, identifier); printf("%d - %d runs with steps of %d\n", sizes_min, sizes_max, sizes_step); printf("Maximum %d retries\n", max_retries); printf("Looped %d times\n", loops); printf("Printing to %s\n", write ? "files" : "stdout"); printf("\n"); const MeasureType *measureTypes[] = { // write sequential // &MeasureType::NOINIT_SEQ_WRITE, &MeasureType::INIT_SEQ_WRITE, // read sequential &MeasureType::NOINIT_SEQ_READ, &MeasureType::INIT_SEQ_READ, // write random // &MeasureType::NOINIT_RND_WRITE, &MeasureType::INIT_RND_WRITE, // read random // &MeasureType::NOINIT_RND_READ, &MeasureType::INIT_RND_READ // }; // open files char retries_str[21]; // enough to hold all numbers up to 64-bits sprintf(retries_str, "%d", max_retries); std::string file_prefix = "read-seq-", failures_file_suffix = "retries-failures.csv", time_file_suffix = "retries-time.csv"; std::string failures_filename = file_prefix + retries_str + failures_file_suffix; //"write-seq-failures.csv"; // std::string time_filename = file_prefix + retries_str + time_file_suffix; //"write-seq-time.csv"; // FILE * failures_out = write ? fopen(failures_filename.c_str(), "w") : stdout; FILE * time_out = fopen(time_filename.c_str(), "w"); // info fprintf(failures_out, "Size (Byte);"); printHeader(measureTypes, sizeof(measureTypes) / sizeof(measureTypes[0]), failures_out); fprintf(time_out, "Size (Byte);"); printHeader(measureTypes, sizeof(measureTypes) / sizeof(measureTypes[0]), time_out); // run suite srand(time(0)); for (int s = sizes_min; s <= sizes_max; s += sizes_step) { fprintf(failures_out, "%lu", s * sizeof(type)); fprintf(time_out, "%lu", s * sizeof(type)); for (int t = 0; t < sizeof(measureTypes) / sizeof(measureTypes[0]); t++) { Stats failureStats; Stats timeStats; float failure_expected_value_sum = 0, failure_variance_sum = 0; float time_expected_value_sum = 0, time_variance_sum = 0; for (int l = 0; l < loops; l++) { int failures = 0; int attempts = 0; std::vector<double> times; for (int il = 0; il < 100; il++) { // init volatile type* array = measureTypes[t]->init(s); // run attempts++; struct timeval start, end; gettimeofday(&start, NULL); int res = measureTypes[t]->run(&array, s); gettimeofday(&end, NULL); double elapsed = ((end.tv_sec - start.tv_sec) * 1000000) + (end.tv_usec - start.tv_usec); times.push_back(elapsed); if (!res) { failures++; } free((void*) array); } // end inner loops loop float failure_rate = (float) failures * 100 / attempts; failureStats.addValue(failure_rate); float time_avg = average(times); timeStats.addValue(time_avg); } // end loops loop fprintf(failures_out, ";%.4f;%.4f", failureStats.getExpectedValue(), failureStats.getStandardDeviation()); fprintf(time_out, ";%.4f;%.4f", timeStats.getExpectedValue(), timeStats.getStandardDeviation()); } // end types loop fprintf(failures_out, "\n"); fprintf(time_out, "\n"); } // end sizes loop fclose(failures_out); fclose(time_out); }