[1257] | 1 | /* |
---|
| 2 | * ---------------------------------------------------------------------- |
---|
| 3 | * P2P: performance test program for worker nodes |
---|
| 4 | * |
---|
| 5 | * This little program gets executed from time to time by each worker |
---|
| 6 | * to measure the performance and available resources of this node. |
---|
| 7 | * It performs a non-trivial calculation involving memory access and |
---|
| 8 | * floating point operations, and returns a single number representing |
---|
| 9 | * the wall time (in microseconds) for this calculation. That wall |
---|
| 10 | * time rolls up the power of the node and its current availability, |
---|
| 11 | * giving a reasonable estimate of how long a similar calculation |
---|
| 12 | * would take. We call this unit of work a "wonk" (WOrker Node |
---|
| 13 | * Kapability). |
---|
| 14 | * ---------------------------------------------------------------------- |
---|
| 15 | * Michael McLennan (mmclennan@purdue.edu) |
---|
| 16 | * ====================================================================== |
---|
[3177] | 17 | * Copyright (c) 2004-2012 HUBzero Foundation, LLC |
---|
[1257] | 18 | * |
---|
| 19 | * See the file "license.terms" for information on usage and |
---|
| 20 | * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
| 21 | * ====================================================================== |
---|
| 22 | */ |
---|
| 23 | #include <stdio.h> |
---|
| 24 | #include <math.h> |
---|
| 25 | #include <stdlib.h> |
---|
| 26 | #include <string.h> |
---|
| 27 | #include <sys/time.h> |
---|
| 28 | |
---|
| 29 | #define LARGE_CHUNK_SIZE 10000000 |
---|
| 30 | #define SMALL_CHUNK_SIZE 1000 |
---|
| 31 | |
---|
| 32 | double ran3(); |
---|
| 33 | |
---|
| 34 | int |
---|
| 35 | main(argc,argv) |
---|
| 36 | int argc; char **argv; /* ignored */ |
---|
| 37 | { |
---|
| 38 | int i, j; |
---|
| 39 | double d, *dvals; |
---|
| 40 | long tval; |
---|
| 41 | struct timeval tstart, tend; |
---|
| 42 | |
---|
| 43 | /* query the starting wall time for this calculation */ |
---|
| 44 | if (gettimeofday(&tstart, (struct timezone*)NULL) < 0) { |
---|
| 45 | exit(1); |
---|
| 46 | } |
---|
| 47 | |
---|
| 48 | /* |
---|
| 49 | * Allocate a large chunk of memory and zero it out. |
---|
| 50 | * This tests available memory and speed of allocation |
---|
| 51 | * to some extent. |
---|
| 52 | */ |
---|
| 53 | dvals = malloc((size_t)(LARGE_CHUNK_SIZE*sizeof(double))); |
---|
| 54 | if (dvals == NULL) { |
---|
| 55 | printf("out of memory\n"); |
---|
| 56 | exit(1); |
---|
| 57 | } |
---|
| 58 | memset(dvals, 0, (size_t)(LARGE_CHUNK_SIZE*sizeof(double))); |
---|
| 59 | |
---|
| 60 | /* |
---|
| 61 | * Scan through the chunk of memory and fill with random |
---|
| 62 | * numbers. This hits lots of memory pages and causes lots |
---|
| 63 | * of integer arithmetic operations. |
---|
| 64 | */ |
---|
| 65 | ran3(-1234); |
---|
| 66 | for (j=0; j < SMALL_CHUNK_SIZE; j++) { |
---|
| 67 | for (i=0; i < LARGE_CHUNK_SIZE; i += SMALL_CHUNK_SIZE) { |
---|
| 68 | dvals[i+j] = ran3(0); |
---|
| 69 | } |
---|
| 70 | } |
---|
| 71 | |
---|
| 72 | /* |
---|
| 73 | * Scan back through again and multiply random numbers together. |
---|
| 74 | * This hits logs of memory pages again and causes lots of |
---|
| 75 | * floating point operations. Use division, since it's more |
---|
| 76 | * expensive than multiplication. |
---|
| 77 | */ |
---|
| 78 | d = 1.0; |
---|
| 79 | for (j=0; j < SMALL_CHUNK_SIZE; j++) { |
---|
| 80 | for (i=0; i < LARGE_CHUNK_SIZE; i += SMALL_CHUNK_SIZE) { |
---|
| 81 | d /= dvals[i+j]; |
---|
| 82 | } |
---|
| 83 | } |
---|
| 84 | |
---|
| 85 | /* query the ending wall time and report the overall time */ |
---|
| 86 | if (gettimeofday(&tend, (struct timezone*)NULL) < 0) { |
---|
| 87 | exit(1); |
---|
| 88 | } |
---|
| 89 | |
---|
| 90 | tval = (tend.tv_sec - tstart.tv_sec)*1000000 |
---|
| 91 | + tend.tv_usec - tstart.tv_usec; |
---|
| 92 | |
---|
[1273] | 93 | printf("rappture-wonks/v1 %ld\n", tval); |
---|
[1257] | 94 | exit(0); |
---|
| 95 | } |
---|
| 96 | |
---|
| 97 | /* |
---|
| 98 | * ---------------------------------------------------------------------- |
---|
| 99 | * FUNCTION: ran3(seed) |
---|
| 100 | * |
---|
| 101 | * This function generates a random number in the range 0.0-1.0. |
---|
| 102 | * Set seed to any negative number to reset the sequence with that |
---|
| 103 | * seed value. |
---|
| 104 | * |
---|
| 105 | * This routine is taken from "Numerical Recipes in C" by by William |
---|
| 106 | * H. Press, Brian P. Flannery, Saul A. Teukolsky, William T. |
---|
| 107 | * Vetterling, Chapter 7, p. 283. |
---|
| 108 | * ---------------------------------------------------------------------- |
---|
| 109 | */ |
---|
| 110 | #define MBIG 1000000000 |
---|
| 111 | #define MSEED 161803398 |
---|
| 112 | #define MZ 0 |
---|
| 113 | #define FAC (1.0/MBIG) |
---|
| 114 | |
---|
| 115 | double |
---|
| 116 | ran3(seed) |
---|
| 117 | long seed; /* pass in negative value to restart */ |
---|
| 118 | { |
---|
| 119 | static int inext, inextp; |
---|
| 120 | static long ma[56]; |
---|
| 121 | static int iff=0; |
---|
| 122 | long mj, mk; |
---|
| 123 | int i, ii, k; |
---|
| 124 | |
---|
| 125 | if (seed < 0 || iff == 0) { |
---|
| 126 | iff = 1; |
---|
| 127 | mj = MSEED - (seed < 0 ? -seed : seed); |
---|
| 128 | mj %= MBIG; |
---|
| 129 | ma[55] = mj; |
---|
| 130 | mk = 1; |
---|
| 131 | for (i=1; i < 54; i++) { |
---|
| 132 | ii = (21*i) % 55; |
---|
| 133 | ma[ii] = mk; |
---|
| 134 | mk = mj - mk; |
---|
| 135 | if (mk < MZ) mk += MBIG; |
---|
| 136 | mj = ma[ii]; |
---|
| 137 | } |
---|
| 138 | for (k=1; k <= 4; k++) { |
---|
| 139 | for (i=1; i <= 55; i++) { |
---|
| 140 | ma[i] -= ma[1+(i+30) % 55]; |
---|
| 141 | if (ma[i] < MZ) ma[i] += MBIG; |
---|
| 142 | } |
---|
| 143 | } |
---|
| 144 | inext = 0; |
---|
| 145 | inextp = 31; |
---|
| 146 | } |
---|
| 147 | if (++inext == 56) inext=1; |
---|
| 148 | if (++inextp == 56) inextp=1; |
---|
| 149 | mj = ma[inext] - ma[inextp]; |
---|
| 150 | if (mj < MZ) mj += MBIG; |
---|
| 151 | ma[inext] = mj; |
---|
| 152 | return mj*FAC; |
---|
| 153 | } |
---|