Blame test/mpi/perf/manyrma.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2010 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
/* This test measures the performance of many rma operations to a single
Packit Service c5cf8c
   target process.
Packit Service c5cf8c
   It uses a number of operations (put or accumulate) to different
Packit Service c5cf8c
   locations in the target window
Packit Service c5cf8c
   This is one of the ways that RMA may be used, and is used in the
Packit Service c5cf8c
   reference implementation of the graph500 benchmark.
Packit Service c5cf8c
*/
Packit Service c5cf8c
#include "mpi.h"
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include <string.h>
Packit Service c5cf8c
Packit Service c5cf8c
#define MAX_COUNT 65536*4
Packit Service c5cf8c
#define MAX_RMA_SIZE 16
Packit Service c5cf8c
#define MAX_RUNS 10
Packit Service c5cf8c
Packit Service c5cf8c
typedef enum { SYNC_NONE = 0,
Packit Service c5cf8c
    SYNC_ALL = -1, SYNC_FENCE = 1, SYNC_LOCK = 2, SYNC_PSCW = 4
Packit Service c5cf8c
} sync_t;
Packit Service c5cf8c
typedef enum { RMA_NONE = 0, RMA_ALL = -1, RMA_PUT = 1, RMA_ACC = 2, RMA_GET = 4 } rma_t;
Packit Service c5cf8c
/* Note GET not yet implemented */
Packit Service c5cf8c
sync_t syncChoice = SYNC_ALL;
Packit Service c5cf8c
rma_t rmaChoice = RMA_ALL;
Packit Service c5cf8c
Packit Service c5cf8c
typedef struct {
Packit Service c5cf8c
    double startOp, endOp, endSync;
Packit Service c5cf8c
} timing;
Packit Service c5cf8c
Packit Service c5cf8c
static int verbose = 1;
Packit Service c5cf8c
static int barrierSync = 0;
Packit Service c5cf8c
static double tickThreshold = 0.0;
Packit Service c5cf8c
Packit Service c5cf8c
void PrintResults(int cnt, timing t[]);
Packit Service c5cf8c
void RunAccFence(MPI_Win win, int destRank, int cnt, int sz, timing t[]);
Packit Service c5cf8c
void RunAccLock(MPI_Win win, int destRank, int cnt, int sz, timing t[]);
Packit Service c5cf8c
void RunPutFence(MPI_Win win, int destRank, int cnt, int sz, timing t[]);
Packit Service c5cf8c
void RunPutLock(MPI_Win win, int destRank, int cnt, int sz, timing t[]);
Packit Service c5cf8c
void RunAccPSCW(MPI_Win win, int destRank, int cnt, int sz,
Packit Service c5cf8c
                MPI_Group exposureGroup, MPI_Group accessGroup, timing t[]);
Packit Service c5cf8c
void RunPutPSCW(MPI_Win win, int destRank, int cnt, int sz,
Packit Service c5cf8c
                MPI_Group exposureGroup, MPI_Group accessGroup, timing t[]);
Packit Service c5cf8c
Packit Service c5cf8c
int main(int argc, char *argv[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int arraysize, i, cnt, sz, maxCount = MAX_COUNT, *arraybuffer;
Packit Service c5cf8c
    int wrank, wsize, destRank, srcRank;
Packit Service c5cf8c
    MPI_Win win;
Packit Service c5cf8c
    MPI_Group wgroup, accessGroup, exposureGroup;
Packit Service c5cf8c
    timing t[MAX_RUNS];
Packit Service c5cf8c
    int maxSz = MAX_RMA_SIZE;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Init(&argc, &argv);
Packit Service c5cf8c
Packit Service c5cf8c
    /* Determine clock accuracy */
Packit Service c5cf8c
    tickThreshold = 10.0 * MPI_Wtick();
Packit Service c5cf8c
    MPI_Allreduce(MPI_IN_PLACE, &tickThreshold, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 1; i < argc; i++) {
Packit Service c5cf8c
        if (strcmp(argv[i], "-put") == 0) {
Packit Service c5cf8c
            if (rmaChoice == RMA_ALL)
Packit Service c5cf8c
                rmaChoice = RMA_NONE;
Packit Service c5cf8c
            rmaChoice |= RMA_PUT;
Packit Service c5cf8c
        } else if (strcmp(argv[i], "-acc") == 0) {
Packit Service c5cf8c
            if (rmaChoice == RMA_ALL)
Packit Service c5cf8c
                rmaChoice = RMA_NONE;
Packit Service c5cf8c
            rmaChoice |= RMA_ACC;
Packit Service c5cf8c
        } else if (strcmp(argv[i], "-fence") == 0) {
Packit Service c5cf8c
            if (syncChoice == SYNC_ALL)
Packit Service c5cf8c
                syncChoice = SYNC_NONE;
Packit Service c5cf8c
            syncChoice |= SYNC_FENCE;
Packit Service c5cf8c
        } else if (strcmp(argv[i], "-lock") == 0) {
Packit Service c5cf8c
            if (syncChoice == SYNC_ALL)
Packit Service c5cf8c
                syncChoice = SYNC_NONE;
Packit Service c5cf8c
            syncChoice |= SYNC_LOCK;
Packit Service c5cf8c
        } else if (strcmp(argv[i], "-pscw") == 0) {
Packit Service c5cf8c
            if (syncChoice == SYNC_ALL)
Packit Service c5cf8c
                syncChoice = SYNC_NONE;
Packit Service c5cf8c
            syncChoice |= SYNC_PSCW;
Packit Service c5cf8c
        } else if (strcmp(argv[i], "-maxsz") == 0) {
Packit Service c5cf8c
            i++;
Packit Service c5cf8c
            maxSz = atoi(argv[i]);
Packit Service c5cf8c
        } else if (strcmp(argv[i], "-maxcount") == 0) {
Packit Service c5cf8c
            i++;
Packit Service c5cf8c
            maxCount = atoi(argv[i]);
Packit Service c5cf8c
        } else if (strcmp(argv[i], "-barrier") == 0) {
Packit Service c5cf8c
            barrierSync = 1;
Packit Service c5cf8c
        } else {
Packit Service c5cf8c
            fprintf(stderr, "Unrecognized argument %s\n", argv[i]);
Packit Service c5cf8c
            fprintf(stderr,
Packit Service c5cf8c
                    "%s [ -put ] [ -acc ] [ -lock ] [ -fence ] [ -pscw ] [ -barrier ]  [ -maxsz msgsize ]\n",
Packit Service c5cf8c
                    argv[0]);
Packit Service c5cf8c
            MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
Packit Service c5cf8c
    MPI_Comm_size(MPI_COMM_WORLD, &wsize);
Packit Service c5cf8c
    destRank = wrank + 1;
Packit Service c5cf8c
    while (destRank >= wsize)
Packit Service c5cf8c
        destRank = destRank - wsize;
Packit Service c5cf8c
    srcRank = wrank - 1;
Packit Service c5cf8c
    if (srcRank < 0)
Packit Service c5cf8c
        srcRank += wsize;
Packit Service c5cf8c
Packit Service c5cf8c
    /* Create groups for PSCW */
Packit Service c5cf8c
    MPI_Comm_group(MPI_COMM_WORLD, &wgroup);
Packit Service c5cf8c
    MPI_Group_incl(wgroup, 1, &destRank, &accessGroup);
Packit Service c5cf8c
    MPI_Group_incl(wgroup, 1, &srcRank, &exposureGroup);
Packit Service c5cf8c
    MPI_Group_free(&wgroup);
Packit Service c5cf8c
Packit Service c5cf8c
    arraysize = maxSz * MAX_COUNT;
Packit Service c5cf8c
    arraybuffer = (int *) malloc(arraysize * sizeof(int));
Packit Service c5cf8c
    if (!arraybuffer) {
Packit Service c5cf8c
        fprintf(stderr, "Unable to allocate %d words\n", arraysize);
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Win_create(arraybuffer, arraysize * sizeof(int), (int) sizeof(int),
Packit Service c5cf8c
                   MPI_INFO_NULL, MPI_COMM_WORLD, &win);
Packit Service c5cf8c
Packit Service c5cf8c
    /* FIXME: we need a test on performance consistency.
Packit Service c5cf8c
     * The test needs to have both a relative growth limit and
Packit Service c5cf8c
     * an absolute limit.
Packit Service c5cf8c
     */
Packit Service c5cf8c
Packit Service c5cf8c
    if (maxCount > MAX_COUNT) {
Packit Service c5cf8c
        fprintf(stderr, "MaxCount must not exceed %d\n", MAX_COUNT);
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if ((syncChoice & SYNC_FENCE) && (rmaChoice & RMA_ACC)) {
Packit Service c5cf8c
        for (sz = 1; sz <= maxSz; sz = sz + sz) {
Packit Service c5cf8c
            if (wrank == 0)
Packit Service c5cf8c
                printf("Accumulate with fence, %d elements\n", sz);
Packit Service c5cf8c
            cnt = 1;
Packit Service c5cf8c
            while (cnt <= maxCount) {
Packit Service c5cf8c
                RunAccFence(win, destRank, cnt, sz, t);
Packit Service c5cf8c
                if (wrank == 0) {
Packit Service c5cf8c
                    PrintResults(cnt, t);
Packit Service c5cf8c
                }
Packit Service c5cf8c
                cnt = 2 * cnt;
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if ((syncChoice & SYNC_LOCK) && (rmaChoice & RMA_ACC)) {
Packit Service c5cf8c
        for (sz = 1; sz <= maxSz; sz = sz + sz) {
Packit Service c5cf8c
            if (wrank == 0)
Packit Service c5cf8c
                printf("Accumulate with lock, %d elements\n", sz);
Packit Service c5cf8c
            cnt = 1;
Packit Service c5cf8c
            while (cnt <= maxCount) {
Packit Service c5cf8c
                RunAccLock(win, destRank, cnt, sz, t);
Packit Service c5cf8c
                if (wrank == 0) {
Packit Service c5cf8c
                    PrintResults(cnt, t);
Packit Service c5cf8c
                }
Packit Service c5cf8c
                cnt = 2 * cnt;
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if ((syncChoice & SYNC_FENCE) && (rmaChoice & RMA_PUT)) {
Packit Service c5cf8c
        for (sz = 1; sz <= maxSz; sz = sz + sz) {
Packit Service c5cf8c
            if (wrank == 0)
Packit Service c5cf8c
                printf("Put with fence, %d elements\n", sz);
Packit Service c5cf8c
            cnt = 1;
Packit Service c5cf8c
            while (cnt <= maxCount) {
Packit Service c5cf8c
                RunPutFence(win, destRank, cnt, sz, t);
Packit Service c5cf8c
                if (wrank == 0) {
Packit Service c5cf8c
                    PrintResults(cnt, t);
Packit Service c5cf8c
                }
Packit Service c5cf8c
                cnt = 2 * cnt;
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if ((syncChoice & SYNC_LOCK) && (rmaChoice & RMA_PUT)) {
Packit Service c5cf8c
        for (sz = 1; sz <= maxSz; sz = sz + sz) {
Packit Service c5cf8c
            if (wrank == 0)
Packit Service c5cf8c
                printf("Put with lock, %d elements\n", sz);
Packit Service c5cf8c
            cnt = 1;
Packit Service c5cf8c
            while (cnt <= maxCount) {
Packit Service c5cf8c
                RunPutLock(win, destRank, cnt, sz, t);
Packit Service c5cf8c
                if (wrank == 0) {
Packit Service c5cf8c
                    PrintResults(cnt, t);
Packit Service c5cf8c
                }
Packit Service c5cf8c
                cnt = 2 * cnt;
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if ((syncChoice & SYNC_PSCW) && (rmaChoice & RMA_PUT)) {
Packit Service c5cf8c
        for (sz = 1; sz <= maxSz; sz = sz + sz) {
Packit Service c5cf8c
            if (wrank == 0)
Packit Service c5cf8c
                printf("Put with pscw, %d elements\n", sz);
Packit Service c5cf8c
            cnt = 1;
Packit Service c5cf8c
            while (cnt <= maxCount) {
Packit Service c5cf8c
                RunPutPSCW(win, destRank, cnt, sz, exposureGroup, accessGroup, t);
Packit Service c5cf8c
                if (wrank == 0) {
Packit Service c5cf8c
                    PrintResults(cnt, t);
Packit Service c5cf8c
                }
Packit Service c5cf8c
                cnt = 2 * cnt;
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if ((syncChoice & SYNC_PSCW) && (rmaChoice & RMA_ACC)) {
Packit Service c5cf8c
        for (sz = 1; sz <= maxSz; sz = sz + sz) {
Packit Service c5cf8c
            if (wrank == 0)
Packit Service c5cf8c
                printf("Accumulate with pscw, %d elements\n", sz);
Packit Service c5cf8c
            cnt = 1;
Packit Service c5cf8c
            while (cnt <= maxCount) {
Packit Service c5cf8c
                RunAccPSCW(win, destRank, cnt, sz, exposureGroup, accessGroup, t);
Packit Service c5cf8c
                if (wrank == 0) {
Packit Service c5cf8c
                    PrintResults(cnt, t);
Packit Service c5cf8c
                }
Packit Service c5cf8c
                cnt = 2 * cnt;
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Win_free(&win);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Group_free(&accessGroup);
Packit Service c5cf8c
    MPI_Group_free(&exposureGroup);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Finalize();
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
void RunAccFence(MPI_Win win, int destRank, int cnt, int sz, timing t[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int k, i, j, one = 1;
Packit Service c5cf8c
Packit Service c5cf8c
    for (k = 0; k < MAX_RUNS; k++) {
Packit Service c5cf8c
        MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_fence(0, win);
Packit Service c5cf8c
        j = 0;
Packit Service c5cf8c
        t[k].startOp = MPI_Wtime();
Packit Service c5cf8c
        for (i = 0; i < cnt; i++) {
Packit Service c5cf8c
            MPI_Accumulate(&one, sz, MPI_INT, destRank, j, sz, MPI_INT, MPI_SUM, win);
Packit Service c5cf8c
            j += sz;
Packit Service c5cf8c
        }
Packit Service c5cf8c
        t[k].endOp = MPI_Wtime();
Packit Service c5cf8c
        if (barrierSync)
Packit Service c5cf8c
            MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_fence(0, win);
Packit Service c5cf8c
        t[k].endSync = MPI_Wtime();
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void RunAccLock(MPI_Win win, int destRank, int cnt, int sz, timing t[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int k, i, j, one = 1;
Packit Service c5cf8c
Packit Service c5cf8c
    for (k = 0; k < MAX_RUNS; k++) {
Packit Service c5cf8c
        MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_lock(MPI_LOCK_SHARED, destRank, 0, win);
Packit Service c5cf8c
        j = 0;
Packit Service c5cf8c
        t[k].startOp = MPI_Wtime();
Packit Service c5cf8c
        for (i = 0; i < cnt; i++) {
Packit Service c5cf8c
            MPI_Accumulate(&one, sz, MPI_INT, destRank, j, sz, MPI_INT, MPI_SUM, win);
Packit Service c5cf8c
            j += sz;
Packit Service c5cf8c
        }
Packit Service c5cf8c
        t[k].endOp = MPI_Wtime();
Packit Service c5cf8c
        if (barrierSync)
Packit Service c5cf8c
            MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_unlock(destRank, win);
Packit Service c5cf8c
        t[k].endSync = MPI_Wtime();
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void RunPutFence(MPI_Win win, int destRank, int cnt, int sz, timing t[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int k, i, j, one = 1;
Packit Service c5cf8c
Packit Service c5cf8c
    for (k = 0; k < MAX_RUNS; k++) {
Packit Service c5cf8c
        MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_fence(0, win);
Packit Service c5cf8c
        j = 0;
Packit Service c5cf8c
        t[k].startOp = MPI_Wtime();
Packit Service c5cf8c
        for (i = 0; i < cnt; i++) {
Packit Service c5cf8c
            MPI_Put(&one, sz, MPI_INT, destRank, j, sz, MPI_INT, win);
Packit Service c5cf8c
            j += sz;
Packit Service c5cf8c
        }
Packit Service c5cf8c
        t[k].endOp = MPI_Wtime();
Packit Service c5cf8c
        if (barrierSync)
Packit Service c5cf8c
            MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_fence(0, win);
Packit Service c5cf8c
        t[k].endSync = MPI_Wtime();
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void RunPutLock(MPI_Win win, int destRank, int cnt, int sz, timing t[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int k, i, j, one = 1;
Packit Service c5cf8c
Packit Service c5cf8c
    for (k = 0; k < MAX_RUNS; k++) {
Packit Service c5cf8c
        MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_lock(MPI_LOCK_SHARED, destRank, 0, win);
Packit Service c5cf8c
        j = 0;
Packit Service c5cf8c
        t[k].startOp = MPI_Wtime();
Packit Service c5cf8c
        for (i = 0; i < cnt; i++) {
Packit Service c5cf8c
            MPI_Put(&one, sz, MPI_INT, destRank, j, sz, MPI_INT, win);
Packit Service c5cf8c
            j += sz;
Packit Service c5cf8c
        }
Packit Service c5cf8c
        t[k].endOp = MPI_Wtime();
Packit Service c5cf8c
        if (barrierSync)
Packit Service c5cf8c
            MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_unlock(destRank, win);
Packit Service c5cf8c
        t[k].endSync = MPI_Wtime();
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void RunPutPSCW(MPI_Win win, int destRank, int cnt, int sz,
Packit Service c5cf8c
                MPI_Group exposureGroup, MPI_Group accessGroup, timing t[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int k, i, j, one = 1;
Packit Service c5cf8c
Packit Service c5cf8c
    for (k = 0; k < MAX_RUNS; k++) {
Packit Service c5cf8c
        MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_post(exposureGroup, 0, win);
Packit Service c5cf8c
        MPI_Win_start(accessGroup, 0, win);
Packit Service c5cf8c
        j = 0;
Packit Service c5cf8c
        t[k].startOp = MPI_Wtime();
Packit Service c5cf8c
        for (i = 0; i < cnt; i++) {
Packit Service c5cf8c
            MPI_Put(&one, sz, MPI_INT, destRank, j, sz, MPI_INT, win);
Packit Service c5cf8c
            j += sz;
Packit Service c5cf8c
        }
Packit Service c5cf8c
        t[k].endOp = MPI_Wtime();
Packit Service c5cf8c
        if (barrierSync)
Packit Service c5cf8c
            MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_complete(win);
Packit Service c5cf8c
        MPI_Win_wait(win);
Packit Service c5cf8c
        t[k].endSync = MPI_Wtime();
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void RunAccPSCW(MPI_Win win, int destRank, int cnt, int sz,
Packit Service c5cf8c
                MPI_Group exposureGroup, MPI_Group accessGroup, timing t[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int k, i, j, one = 1;
Packit Service c5cf8c
Packit Service c5cf8c
    for (k = 0; k < MAX_RUNS; k++) {
Packit Service c5cf8c
        MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_post(exposureGroup, 0, win);
Packit Service c5cf8c
        MPI_Win_start(accessGroup, 0, win);
Packit Service c5cf8c
        j = 0;
Packit Service c5cf8c
        t[k].startOp = MPI_Wtime();
Packit Service c5cf8c
        for (i = 0; i < cnt; i++) {
Packit Service c5cf8c
            MPI_Accumulate(&one, sz, MPI_INT, destRank, j, sz, MPI_INT, MPI_SUM, win);
Packit Service c5cf8c
            j += sz;
Packit Service c5cf8c
        }
Packit Service c5cf8c
        t[k].endOp = MPI_Wtime();
Packit Service c5cf8c
        if (barrierSync)
Packit Service c5cf8c
            MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
        MPI_Win_complete(win);
Packit Service c5cf8c
        MPI_Win_wait(win);
Packit Service c5cf8c
        t[k].endSync = MPI_Wtime();
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void PrintResults(int cnt, timing t[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int k;
Packit Service c5cf8c
    double d1 = 0, d2 = 0;
Packit Service c5cf8c
    double minD1 = 1e10, minD2 = 1e10;
Packit Service c5cf8c
    double tOp, tSync;
Packit Service c5cf8c
    for (k = 0; k < MAX_RUNS; k++) {
Packit Service c5cf8c
        tOp = t[k].endOp - t[k].startOp;
Packit Service c5cf8c
        tSync = t[k].endSync - t[k].endOp;
Packit Service c5cf8c
        d1 += tOp;
Packit Service c5cf8c
        d2 += tSync;
Packit Service c5cf8c
        if (tOp < minD1)
Packit Service c5cf8c
            minD1 = tOp;
Packit Service c5cf8c
        if (tSync < minD2)
Packit Service c5cf8c
            minD2 = tSync;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (verbose) {
Packit Service c5cf8c
        long rate = 0;
Packit Service c5cf8c
        /* Use the minimum times because they are more stable - if timing
Packit Service c5cf8c
         * accuracy is an issue, use the min over multiple trials */
Packit Service c5cf8c
        d1 = minD1;
Packit Service c5cf8c
        d2 = minD2;
Packit Service c5cf8c
        /* d1 = d1 / MAX_RUNS; d2 = d2 / MAX_RUNS); */
Packit Service c5cf8c
        if (d2 > 0)
Packit Service c5cf8c
            rate = (long) (cnt) / d2;
Packit Service c5cf8c
        /* count, op, sync, op/each, sync/each, rate */
Packit Service c5cf8c
        printf("%d\t%e\t%e\t%e\t%e\t%ld\n", cnt, d1, d2, d1 / cnt, d2 / cnt, rate);
Packit Service c5cf8c
    }
Packit Service c5cf8c
}