Beispiel #1
0
/**
 * \brief computes the differences of two time stamps with respecting overflow
 *
 * This function also accounts for the overhead when taking timestamps
 *
 * \param tsc_start timestamp of start
 * \param tsc_end   timestamp of end
 *
 * \return elaped cycles
 */
cycles_t bench_time_diff(cycles_t tsc_start, cycles_t tsc_end)
{
    if (!bench_is_initialized) {
        bench_init();
    }

    cycles_t result;
    if (tsc_end < tsc_start) {
        result = (LONG_MAX - tsc_start) + tsc_end - bench_tscoverhead();
    } else {
        result = (tsc_end - tsc_start - bench_tscoverhead());
    }
    return result;
}
Beispiel #2
0
static void test(char *base, size_t size, size_t runs, reset_fn reset, measure_fn measure, const char *name)
{
    assert(size % sizeof(struct cte) == 0);
    struct cte *ctes = (struct cte*)base;
    size_t num_caps = size/sizeof(struct cte);

    int run, skipped;
    for (run = skipped = 0;
         run < runs && (skipped < runs/10 || skipped < run*2);
         run++)
    {
        // reset MDB
        reset(base, size);

        // perform measurement
        cycles_t val = measure(ctes, num_caps);

        if (!val) {
            // measurement skipped
            printf("%s: skipping\n", name);
            skipped++;
            run--;
            continue;
        }

        // output
        printf("%s: %"PRIu64"/%lu\n", name, val - bench_tscoverhead(), num_caps);
    }

    if (run < runs) {
        printf("%s: skipped too many, aborting\n", name);
    }
}
Beispiel #3
0
void experiment(coreid_t idx)
{
    timestamps = malloc(sizeof(struct timestamps) * MAX_COUNT);
    assert(timestamps != NULL);

    struct bench_ump_binding *bu = (struct bench_ump_binding*)array[idx];
    struct flounder_ump_state *fus = &bu->ump_state;
    struct ump_chan *chan = &fus->chan;

    struct ump_chan_state *send = &chan->send_chan;
    struct ump_chan_state *recv = &chan->endpoint.chan;

    printf("Running latency between core %"PRIuCOREID" and core %"PRIuCOREID"\n", my_core_id, idx);

    /* Run experiment */
    for (int i = 0; i < MAX_COUNT; i++) {
        volatile struct ump_message *msg;
        struct ump_control ctrl;
        timestamps[i].time0 = bench_tsc();
        msg = ump_impl_get_next(send, &ctrl);
        msg->header.control = ctrl;
        while (!ump_impl_recv(recv));
        timestamps[i].time1 = bench_tsc();
    }

    /* Print results */
    for (int i = MAX_COUNT / 10; i < MAX_COUNT; i++) {
        if (timestamps[i].time1 > timestamps[i].time0) {
            printf("page %d took %"PRIuCYCLES"\n", i,
                   timestamps[i].time1 - bench_tscoverhead() -
                   timestamps[i].time0);
        }
    }
}
Beispiel #4
0
static void start_experiment(void)
{
    errval_t err;

    for (int i = 1; i < num_cores; i++) {

        int count = 0;
        experiment_flag = false;
        experiment_count = i;
        for (int j = 0; j < MAX_CPUS; j++) {
            if (array[j]) {
                while(1) {
                    err = array[j]->tx_vtbl.shmc_start(array[j], NOP_CONT);
                    if (err_is_ok(err)) {
                        break;
                    } else if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
                        messages_wait_and_handle_next();
                    } else {
                        USER_PANIC_ERR(err, "sending shmc_start failed");
                    }
                }
                count++;
                if (count == i) {
                    break;
                }
            }
        }
        run_experiment();

        printf("Running on %d cores\n", i + 1);
        for (int j = 0; j < MAX_COUNT; j++) {
            printf("page %d took %"PRIuCYCLES"\n", j,
                   timestamps[j].time1 - timestamps[j].time0 - bench_tscoverhead());
        }

        while(!experiment_flag) {
            messages_wait_and_handle_next();
        }
    }
    printf("client done\n");
}
Beispiel #5
0
// continue experiment
static void experiment_cont(void* arg)
{

    errval_t err;
    static bool flag = false;
    static int message_type = 0;

    // Experiment finished (with this message type)
    if (i == MAX_COUNT - 1) {

#if CONFIG_TRACE
#else
        // print measured times
        for (int j = MAX_COUNT / 10; j < MAX_COUNT; j++) {

            printf(
                    "page %d took %"PRIuCYCLES"\n",
                    j,
                    timestamps[j].time1 - bench_tscoverhead()
                            - timestamps[j].time0);
        }
#endif
        // go to next message type
        message_type++;
        flag = false;
        i = 0;
        if (message_type > 13) {

            // stop tracing
            err = trace_event(TRACE_SUBSYS_MULTIHOP,
                    TRACE_EVENT_MULTIHOP_BENCH_STOP, 0);
            if (err_is_fail(err)) {
                USER_PANIC_ERR(err, "trace_event failed");
            }

#if CONFIG_TRACE
            // dump trace
            char *buf = malloc(50*4096*4096);
            size_t length = trace_dump(buf, 20*4096*4096, NULL);
            printf("%s\n", buf);
            printf("length of buffer %lu\n", length);
#endif
            printf("client done!\n");
            return;
        }
    }

    if (!flag) { // Start experiment

#if CONFIG_TRACE
#else
        printf("Running latency test for message %s...\n",
                get_message_name(message_type));
#endif
        flag = true;
        timestamps[i].time0 = bench_tsc();
    } else { // Continue experiment
        i++;
        timestamps[i].time0 = bench_tsc();
    }

    // trace send event
    err = trace_event(TRACE_SUBSYS_MULTIHOP, TRACE_EVENT_MULTIHOP_MESSAGE_SEND,
            message_type);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "trace_event failed");
    }

    // send next message
    switch (message_type) {
    case 0:
        err = binding->tx_vtbl.fsb_empty_request(binding, NOP_CONT);
        break;
    case 1:
        err = binding->tx_vtbl.fsb_payload32_1_request(binding, NOP_CONT, 1);
        break;

    case 2:
        err = binding->tx_vtbl.fsb_payload32_2_request(binding, NOP_CONT, 1, 2);
        break;

    case 3:
        err = binding->tx_vtbl.fsb_payload32_4_request(binding, NOP_CONT, 1, 2,
                3, 4);
        break;

    case 4:
        err = binding->tx_vtbl.fsb_payload32_8_request(binding, NOP_CONT, 1, 2,
                3, 4, 5, 6, 7, 8);
        break;

    case 5:
        err = binding->tx_vtbl.fsb_payload32_16_request(binding, NOP_CONT, 1, 2,
                3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
        break;

    case 6:
        err = binding->tx_vtbl.fsb_payload64_1_request(binding, NOP_CONT, 1);
        break;

    case 7:
        err = binding->tx_vtbl.fsb_payload64_2_request(binding, NOP_CONT, 1, 2);
        break;

    case 8:
        err = binding->tx_vtbl.fsb_payload64_4_request(binding, NOP_CONT, 1, 2,
                3, 4);
        break;

    case 9:
        err = binding->tx_vtbl.fsb_payload64_8_request(binding, NOP_CONT, 1, 2,
                3, 4, 5, 6, 7, 8);
        break;

    case 10:
        err = binding->tx_vtbl.fsb_payload64_16_request(binding, NOP_CONT, 1, 2,
                3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
        break;

    case 11:
        err = binding->tx_vtbl.fsb_buffer_request(binding, NOP_CONT, &buffer,
                1);
        break;

    case 12:
        err = binding->tx_vtbl.fsb_buffer_request(binding, NOP_CONT, buffer2,
                100);
        break;

    case 13:
        err = binding->tx_vtbl.fsb_buffer_request(binding, NOP_CONT, buffer3,
                1000);
        break;

    default:
        printf("unknown message type\n");
        abort();
        break;
    }

    // make sure send was successful
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "while running experiment\n");
    }

    // receive reply (by dispatching events from the
    // waitset we use for the benchmark)
    while (reply_received == false) {
        event_dispatch(&signal_waitset);
    }

    experiment();
}