Пример #1
0
static void print_results(void)
{
    int i;
    int t;
    unsigned long long tasks_max[nr_tasks];
    unsigned long long tasks_min[nr_tasks];
    unsigned long long tasks_avg[nr_tasks];

    memset(tasks_max, 0, sizeof(tasks_max[0])*nr_tasks);
    memset(tasks_min, 0xff, sizeof(tasks_min[0])*nr_tasks);
    memset(tasks_avg, 0, sizeof(tasks_avg[0])*nr_tasks);

    printf("Iter: ");
    for (t = 0; t < nr_tasks; t++)
        printf("%6d  ", t);
    printf("\n");

    for (t = 0; t < nr_tasks; t++) {
        tasks_max[t] = stats_max(&intervals[t]);
        tasks_min[t] = stats_min(&intervals[t]);
        tasks_avg[t] = stats_avg(&intervals[t]);
    }
    for (i = 0; i < nr_runs; i++) {
        printf("%4d:   ", i);
        for (t = 0; t < nr_tasks; t++)
            printf("%6ld  ", intervals[t].records[i].y);

        printf("\n");
        printf(" len:   ");
        for (t = 0; t < nr_tasks; t++)
            printf("%6ld  ", intervals_length[t].records[i].y);

        printf("\n");
        printf(" loops: ");
        for (t = 0; t < nr_tasks; t++)
            printf("%6ld  ", intervals_loops[t].records[i].y);

        printf("\n");
        printf("\n");
    }

    printf("Parent pid: %d\n", getpid());

    for (t = 0; t < nr_tasks; t++) {
        printf(" Task %d (prio %d) (pid %ld):\n", t, t + prio_start,
               thread_pids[t]);
        printf("   Max: %lld us\n", tasks_max[t]);
        printf("   Min: %lld us\n", tasks_min[t]);
        printf("   Tot: %lld us\n", tasks_avg[t] * nr_runs);
        printf("   Avg: %lld us\n", tasks_avg[t]);
        printf("\n");
    }

    printf(" Result: %s\n", (check < 0) ? "FAIL" : "PASS");
}
Пример #2
0
void * high_prio_thread(void *arg)
{
	nsec_t high_start, high_end, high_get_lock;
	unsigned int i;

	stats_container_init(&cpu_delay_dat, iterations);
	stats_container_init(&cpu_delay_hist, HIST_BUCKETS);
	stats_quantiles_init(&cpu_delay_quantiles, (int)log10(iterations));

	printf("High prio thread started\n");

	for (i = 0; i < iterations; i++) {
		/* Wait for all threads to reach barrier wait. When
		   woken up, low prio thread will own the mutex
		 */
		pthread_barrier_wait(&bar1);

		high_start = rt_gettime();
		pthread_mutex_lock(&lock);
		high_end = rt_gettime();
		high_get_lock = high_end - low_unlock;

		busy_work_ms(high_work_time);
		pthread_mutex_unlock(&lock);

		rec.x = i;
		rec.y = high_get_lock / NS_PER_US;
		stats_container_append(&cpu_delay_dat, rec);

		/* Wait for all threads to finish this iteration */
		pthread_barrier_wait(&bar2);
	}

	stats_hist(&cpu_delay_hist, &cpu_delay_dat);
	stats_container_save("samples", "pi_perf Latency Scatter Plot",
				"Iteration", "Latency (us)", &cpu_delay_dat, "points");
	stats_container_save("hist", "pi_perf Latency Histogram",
				"Latency (us)", "Samples", &cpu_delay_hist, "steps");

	printf("Time taken for high prio thread to get the lock once released by low prio thread\n");
	printf("Min delay = %ld us\n", stats_min(&cpu_delay_dat));
	printf("Max delay = %ld us\n", stats_max(&cpu_delay_dat));
	printf("Average delay = %4.2f us\n", stats_avg(&cpu_delay_dat));
	printf("Standard Deviation = %4.2f us\n", stats_stddev(&cpu_delay_dat));
	printf("Quantiles:\n");
	stats_quantiles_calc(&cpu_delay_dat, &cpu_delay_quantiles);
	stats_quantiles_print(&cpu_delay_quantiles);

	max_pi_delay = stats_max(&cpu_delay_dat);

	return NULL;
}
Пример #3
0
int periodic_thread(nsec_t period, int iterations, int loops)
{
	stats_container_t dat;
	stats_container_t hist;
	stats_quantiles_t quantiles;
	stats_record_t rec;

	int i = 0;
	int fail = 0;
	nsec_t next, now;
	nsec_t exe_start, exe_end, exe_time;
	char *samples_filename;
	char *hist_filename;

	stats_container_init(&dat, iterations);
	stats_container_init(&hist, HIST_BUCKETS);
	stats_quantiles_init(&quantiles, (int)log10(iterations));
	if (asprintf(&samples_filename, "%s-samples", filename_prefix) == -1) {
		fprintf(stderr, "Failed to allocate string for samples filename\n");
		return -1;
	}

	if (asprintf(&hist_filename, "%s-hist", filename_prefix) == -1) {
		fprintf(stderr, "Failed to allocate string for samples filename\n");
		return -1;
	}
	next = rt_gettime();
	while (i < iterations) {
		next += period;
		now = rt_gettime();
		if (now > next) {
			printf("Missed period, aborting (didn't get scheduled in time)\n");
			fail = 1;
			break;
		}
		exe_start = rt_gettime();
		calc(loops);
		exe_end = rt_gettime();
		exe_time = exe_end - exe_start;
		rec.x = i;
		rec.y = exe_time/NS_PER_US;
		stats_container_append(&dat, rec);

		i++;

		now = rt_gettime();
		if (now > next) {
			printf("Missed period, aborting (calc took too long)\n");
			fail = 1;
			break;
		}
		rt_nanosleep(next - now);
	}

	stats_container_save(samples_filename, "Periodic CPU Load Scatter Plot",\
			     "Iteration", "Runtime (us)", &dat, "points");
	stats_container_save(hist_filename, "Periodic CPU Load Histogram",\
			     "Runtime (us)", "Samples", &hist, "steps");

	printf("  Execution Time Statistics:\n");
	printf("Min: %ld us\n", stats_min(&dat));
	printf("Max: %ld us\n", stats_max(&dat));
	printf("Avg: %.4f us\n", stats_avg(&dat));
	printf("StdDev: %.4f us\n", stats_stddev(&dat));
	printf("Quantiles:\n");
	stats_quantiles_calc(&dat, &quantiles);
	stats_quantiles_print(&quantiles);
	printf("Criteria: no missed periods\n");
	printf("Result: %s\n", fail ? "FAIL":"PASS");

	free(samples_filename);
	free(hist_filename);

	return fail;
}
Пример #4
0
void *signal_receiving_thread(void *arg)
{
	int i, ret, sig;
	long delta;
	long max, min;
	sigset_t set, oset;

	stats_container_t dat;
	stats_container_t hist;
	stats_quantiles_t quantiles;
	stats_record_t rec;

	stats_container_init(&dat, ITERATIONS);
	stats_container_init(&hist, HIST_BUCKETS);
	stats_quantiles_init(&quantiles, (int)log10(ITERATIONS));

	debug(DBG_DEBUG, "Signal receiving thread running\n");

	if ((sigaddset(&set, SIGNALNUMBER))) {
		perror("sigaddset:");
		exit(1);
	}
	if ((ret = pthread_sigmask(SIG_BLOCK, &set, &oset))) {
		printf("pthread_sigmask returned %d\n", ret);
		exit(1);
	}

	/* Let the sending thread know that receiver is ready */
	atomic_set(1, &flag);

	debug(DBG_DEBUG, "Signal receiving thread ready to receive\n");

	if (latency_threshold) {
		latency_trace_enable();
		latency_trace_start();
	}

	/* Warm up */
	for (i = 0; i < 5; i++) {
		sigwait(&set, &sig);
		atomic_set(1, &flag);
	}

	max = min = 0;
	fail = 0;
	debug(DBG_INFO, "\n\n");

	for (i = 0; i < ITERATIONS; i++) {
		sigwait(&set, &sig);
		end = rt_gettime();
		delta = (end - begin)/NS_PER_US;
		rec.x = i;
		rec.y = delta;
		stats_container_append(&dat, rec);

		if (i == 0 || delta < min)
			min = delta;

		if (delta > max)
			max = delta;

		if (delta > pass_criteria) fail++;

		debug(DBG_INFO, "Iteration %d: Took %ld us. Max = %ld us, "
		      "Min = %ld us\n", i, delta, max, min);

		fflush(stdout);
		buffer_print();

		if (latency_threshold && (delta > latency_threshold)) {
			atomic_set(2, &flag);
			break;
		}

		atomic_set(1, &flag);
	}

	if (latency_threshold) {
		latency_trace_stop();

		if (i != ITERATIONS) {
			printf("Latency threshold (%luus) exceeded at iteration %d\n",
			       latency_threshold, i);
			fflush(stdout);
			buffer_print();
			latency_trace_print();
			stats_container_resize(&dat, i + 1);
		}
	}

	stats_hist(&hist, &dat);
	stats_container_save("samples", "pthread_kill Latency Scatter Plot",
			     "Iteration", "Latency (us)", &dat, "points");
	stats_container_save("hist", "pthread_kill Latency Histogram",
			     "Latency (us)", "Samples", &hist, "steps");

	printf("\n");
	printf("Min: %lu us\n", stats_min(&dat));
	printf("Max: %lu us\n", stats_max(&dat));
	printf("Avg: %.4f us\n", stats_avg(&dat));
	printf("StdDev: %.4f us\n", stats_stddev(&dat));
	printf("Quantiles:\n");
	stats_quantiles_calc(&dat, &quantiles);
	stats_quantiles_print(&quantiles);
	printf("Failures: %d\n", fail);
	printf("Criteria: Time < %d us\n", (int)pass_criteria);
	printf("Result: %s", fail ? "FAIL" : "PASS");
	printf("\n\n");

	return NULL;
}
Пример #5
0
int main(int argc, char *argv[])
{
	int i;
	setup();

	rt_init("hi:", parse_args, argc, argv);

	if (iterations < 100) {
		fprintf(stderr, "Number of iteration cannot be less than 100.\n");
		exit(1);
	}

	printf("------------------------------------\n");
	printf("Periodic CPU Load Execution Variance\n");
	printf("------------------------------------\n\n");
	printf("Running %d iterations per thread\n", iterations);
	printf("Thread Group A:\n");
	printf("  threads: %d\n", THREADS_PER_GROUP);
	printf("  priority: %d\n", PRIO_A);
	printf("  period: %d ms\n", PERIOD_A/NS_PER_MS);
	printf("Thread Group B:\n");
	printf("  threads: %d\n", THREADS_PER_GROUP);
	printf("  priority: %d\n", PRIO_B);
	printf("  period: %d ms\n", PERIOD_B/NS_PER_MS);
	printf("Thread Group C:\n");
	printf("  threads: %d\n", THREADS_PER_GROUP);
	printf("  priority: %d\n", PRIO_C);
	printf("  period: %d ms\n", PERIOD_C/NS_PER_MS);
	printf("\n");

	for (i=0; i<(THREADS_PER_GROUP * NUM_GROUPS); i++) {
		stats_container_init(&dat[i], iterations);
		stats_quantiles_init(&quantiles[i], (int)log10(iterations));
	}

	struct periodic_arg parg_a = {PERIOD_A, iterations, calc, (void *)CALC_LOOPS_A };
	struct periodic_arg parg_b = {PERIOD_B, iterations, calc, (void *)CALC_LOOPS_B };
	struct periodic_arg parg_c = {PERIOD_C, iterations, calc, (void *)CALC_LOOPS_C };

	for (i=0; i < THREADS_PER_GROUP; i++)
		create_fifo_thread(periodic_thread, (void*)&parg_a, PRIO_A);
	for (i=0; i < THREADS_PER_GROUP; i++)
		create_fifo_thread(periodic_thread, (void*)&parg_b, PRIO_B);
	for (i=0; i < THREADS_PER_GROUP; i++)
		create_fifo_thread(periodic_thread, (void*)&parg_c, PRIO_C);

	join_threads();

	printf("\nExecution Time Statistics:\n\n");

	for (i=0; i<(THREADS_PER_GROUP * NUM_GROUPS); i++) {
		printf("TID %d (%c)\n", i, groupname[i>>2]);
		printf("  Min: %ld us\n", stats_min(&dat[i]));
		printf("  Max: %ld us\n", stats_max(&dat[i]));
		printf("  Avg: %f us\n", stats_avg(&dat[i]));
		printf("  StdDev: %f us\n\n", stats_stddev(&dat[i]));
		printf("  Quantiles:\n");
		stats_quantiles_calc(&dat[i], &quantiles[i]);
		stats_quantiles_print(&quantiles[i]);
		printf("Criteria: TID %d did not miss a period\n", i);
		printf("Result: %s\n", fail[i] ? "FAIL":"PASS");
		printf("\n");

		if (fail[i])
			ret = 1;
	}

	// FIXME: define pass criteria
	// printf("\nCriteria: latencies < %d us\n", PASS_US);
	// printf("Result: %s\n", ret ? "FAIL" : "PASS");

	for (i=0; i<(THREADS_PER_GROUP * NUM_GROUPS); i++) {
		stats_container_free(&dat[i]);
		stats_quantiles_free(&quantiles[i]);
	}

	return ret;
}
Пример #6
0
void main_thread(void)
{
	int ret, i, j;
	nsec_t start, end;
	long smin = 0, smax = 0, cmin = 0, cmax = 0, delta = 0;
	float savg, cavg;
	int cpuid;

	if (	stats_container_init(&sdat, iterations) ||
		stats_container_init(&shist, HIST_BUCKETS) ||
		stats_container_init(&cdat, iterations) ||
		stats_container_init(&chist, HIST_BUCKETS)
	)
	{
		fprintf (stderr, "Cannot init stats container\n");
		exit(1);
	}

	tids = malloc(sizeof(int) * numcpus);
	if (!tids) {
		perror("malloc");
		exit(1);
	}
	memset(tids, 0, numcpus);

	cpuid = set_affinity();
	if (cpuid == -1) {
		fprintf(stderr, "Main thread: Can't set affinity.\n");
		exit(1);
	}

	/* run matrix mult operation sequentially */
	curdat = &sdat;
	curdat->index = iterations-1;
	printf("\nRunning sequential operations\n");
	start = rt_gettime();
	for (i = 0; i < iterations; i++)
		matrix_mult_record(MATRIX_SIZE, i);
	end = rt_gettime();
	delta = (long)((end - start)/NS_PER_US);

	savg = delta/iterations; /* don't use the stats record, use the total time recorded */
	smin = stats_min(&sdat);
	smax = stats_max(&sdat);

	printf("Min: %ld us\n", smin);
	printf("Max: %ld us\n", smax);
	printf("Avg: %.4f us\n", savg);
	printf("StdDev: %.4f us\n", stats_stddev(&sdat));

	if (
		stats_hist(&shist, &sdat) ||

		stats_container_save("sequential", "Matrix Multiplication Sequential Execution Runtime Scatter Plot",
				"Iteration", "Runtime (us)", &sdat, "points") ||
		stats_container_save("sequential_hist", "Matrix Multiplicatoin Sequential Execution Runtime Histogram",
				"Runtime (us)", "Samples", &shist, "steps")
	) {
		fprintf(stderr, "Warning: could not save sequential mults stats\n");
	}

	pthread_barrier_init(&mult_start, NULL, numcpus+1);
	set_priority(PRIO);
	curdat = &cdat;
	curdat->index = iterations-1;
	online_cpu_id = -1; /* Redispatch cpus */
	/* Create numcpus-1 concurrent threads */
	for (j = 0; j < numcpus; j++) {
		tids[j] = create_fifo_thread(concurrent_thread, NULL, PRIO);
		if (tids[j] == -1) {
			printf("Thread creation failed (max threads exceeded?)\n");
			exit(1);
		}
	}

	/* run matrix mult operation concurrently */
	printf("\nRunning concurrent operations\n");
	pthread_barrier_wait(&mult_start);
	start = rt_gettime();
	join_threads();
	end = rt_gettime();

	delta = (long)((end - start)/NS_PER_US);

	cavg = delta/iterations; /* don't use the stats record, use the total time recorded */
	cmin = stats_min(&cdat);
	cmax = stats_max(&cdat);

	printf("Min: %ld us\n", cmin);
	printf("Max: %ld us\n", cmax);
	printf("Avg: %.4f us\n", cavg);
	printf("StdDev: %.4f us\n", stats_stddev(&cdat));

	if (
		stats_hist(&chist, &cdat) ||

		stats_container_save("concurrent", "Matrix Multiplication Concurrent Execution Runtime Scatter Plot",
					"Iteration", "Runtime (us)", &cdat, "points") ||
		stats_container_save("concurrent_hist", "Matrix Multiplication Concurrent Execution Runtime Histogram",
					"Iteration", "Runtime (us)", &chist, "steps")
	) {
		fprintf(stderr, "Warning: could not save concurrent mults stats\n");
	}

	printf("\nConcurrent Multipliers:\n");
	printf("Min: %.4f\n", (float)smin/cmin);
	printf("Max: %.4f\n", (float)smax/cmax);
	printf("Avg: %.4f\n", (float)savg/cavg);

	ret = 1;
	if (savg > (cavg * criteria))
		ret = 0;
	printf("\nCriteria: %.2f * average concurrent time < average sequential time\n",
		criteria);
	printf("Result: %s\n", ret ? "FAIL" : "PASS");

	return;
}