lkml.org 
[lkml]   [2005]   [Jul]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    Subjecti387 floating-point test program/benchmark
    /* fp.c: i387 benchmark/test program */

    #define FP_VERSION "0.10"
    #define _GNU_SOURCE
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <signal.h>
    #include <sched.h>

    #define COND_YIELD(iters, ctr) \
    if ((iters) > 0 && ++(ctr) > (iters)) { \
    (ctr) = 0; \
    sched_yield(); \
    }
    #define RDTSCLL(r) __asm__ __volatile__("rdtsc" : "=A" (r))

    int fp = 0, in = 0, yi = 0;
    volatile int lo = 0, lo2 = 0;
    int p_ctr = 0, c_ctr = 0, get;
    long long i, c_iters, p_iters = 0;
    long double c_res, p_res;
    unsigned long long tsc1, tsc2;
    cpu_set_t cpuset;

    static void handler(int sig)
    {
    lo = 0; /* child exited -- stop looping */
    }
    struct sigaction sa = {
    .sa_handler = handler,
    };

    void usage(char *prog)
    {
    printf("\n i387 floating point benchmark/test program v" FP_VERSION);
    printf("\n\n Usage:\n");
    printf("\t%s [-f] [-i] [-a] [-y count] loops\n\n", prog);
    printf("\t-f : loop in parent process waiting for child to exit\n");
    printf("\t-i : do integer math while looping instead of FP math\n");
    printf("\t (-f and -i: do one FP operation, then use integer math)\n");
    printf("\t-a : run parent and child on single cpu\n");
    printf("\t-y : yield CPU every 'count' loops in parent and child\n\n");
    exit(1);
    }

    static void do_parent()
    {
    if (fp)
    __asm__ __volatile__("fld1 ; fldz");

    while (lo) {
    if (fp & !in)
    __asm__ __volatile__("fadd %st(1), %st(0)");
    else
    p_iters++;

    COND_YIELD(yi, p_ctr);
    }

    if (fp)
    __asm__ __volatile__("fxch ; fstpt p_res ; fstpt p_res");
    if (fp & !in)
    p_iters = (long long)p_res;

    printf("Parent did: %12lld loops\n", p_iters);
    }

    static void do_child()
    {
    RDTSCLL(tsc1);
    __asm__ __volatile__("fld1 ; fldz");
    for (i = 0; i < c_iters; i++) {
    __asm__ __volatile__("fadd %st(1), %st(0)");
    COND_YIELD(yi, c_ctr);
    }
    __asm__ __volatile__("fxch ; fstpt c_res ; fstpt c_res");
    RDTSCLL(tsc2);

    if (c_res != (long double)c_iters)
    printf("FP error! Result was %Lg; expected %lld\n", c_res, c_iters);

    printf("CPU clocks: %12llu\n", tsc2 - tsc1);
    }

    int main(int argc, char * argv[])
    {
    do {
    get = getopt(argc, argv, "fiay:");
    switch (get) {
    case 'f':
    fp = 1;
    break;
    case 'i':
    in = 1;
    break;
    case 'a':
    memset(&cpuset, sizeof(cpuset), 0);
    CPU_SET(1, &cpuset);
    sched_setaffinity(0, &cpuset);
    break;
    case 'y':
    yi = atoi(optarg);
    if (yi == 0)
    get = '?';
    break;
    default:
    break;
    }

    } while (get != -1 && get != '?');

    if (get == '?' || optind >= argc)
    usage(argv[0]);

    c_iters = atoll(argv[optind]);

    if (fp | in) {
    sigaction(SIGCHLD, &sa, NULL);
    lo2 = lo = 1;
    }

    if (fork())
    if (lo2)
    do_parent();
    else
    wait(NULL);
    else
    do_child();

    return 0;
    }
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-07-29 23:22    [W:0.025 / U:2.712 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site