1/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. 2 * 3 * giantAsmBench.c - Benchmark of platform-specific giantInteger primitives. 4 * 5 * Revision History 6 * ---------------- 7 * 18 Apr 98 Doug Mitchell at Apple 8 * Created. 9 */ 10 11#include <security_cryptkit/giantPortCommon.h> 12#include <security_cryptkit/feeDebug.h> 13#include <security_cryptkit/feeFunctions.h> 14#include <stdlib.h> 15#include "ckutilsPlatform.h" 16#include <stdio.h> 17#include <time.h> 18 19#define LOOPS_DEF 10000 20#define MIN_SIZE_DEF 1 /* mix digits for vectorMultiply test */ 21#define MAX_SIZE_DEF 8 /* max digits */ 22 23 24static void usage(char **argv) 25{ 26 printf("usage: %s [options]\n", argv[0]); 27 printf(" Options:\n"); 28 printf(" l=loops (default = %d)\n", LOOPS_DEF); 29 printf(" n=maxDigits (default = %d)\n", MIN_SIZE_DEF); 30 printf(" x=maxDigits (default = %d)\n", MAX_SIZE_DEF); 31 printf(" s=seed\n"); 32 printf(" h(elp)\n"); 33 exit(1); 34} 35 36/* 37 * Fill buffer with random data. Assumes giantDigits is native int size. 38 */ 39static void randDigits(unsigned numDigits, 40 giantDigit *digits) 41{ 42 int i; 43 44 for(i=0; i<numDigits; i++) { 45 /* RAND() only returns 31 bits on Unix.... */ 46 digits[i]= RAND() + ((RAND() & 1) << 31); 47 } 48} 49 50 51 52int main(int argc, char **argv) 53{ 54 int arg; 55 char *argp; 56 giantDigit *digit1; // mallocd arrays 57 giantDigit *digit2; 58 giantDigit *vect1; 59 giantDigit *vect2; 60 giantDigit *dig1p; // ptr into mallocd arrays 61 giantDigit *dig2p; 62 giantDigit *vect1p; 63 giantDigit *vect2p; 64 unsigned numDigits; 65 unsigned i; 66 PLAT_TIME startTime; 67 PLAT_TIME endTime; 68 unsigned elapsed; 69 giantDigit scr1; // op result 70 giantDigit scr2; // op result 71 int loops = LOOPS_DEF; 72 int seedSpec = 0; 73 unsigned seed = 0; 74 unsigned maxSize = MAX_SIZE_DEF; 75 unsigned minSize = MIN_SIZE_DEF; 76 77 initCryptKit(); 78 79 #if macintosh 80 argc = ccommand(&argv); 81 #endif 82 83 for(arg=1; arg<argc; arg++) { 84 argp = argv[arg]; 85 switch(argp[0]) { 86 case 'x': 87 maxSize = atoi(&argp[2]); 88 break; 89 case 'n': 90 minSize = atoi(&argp[2]); 91 break; 92 case 'l': 93 loops = atoi(&argp[2]); 94 break; 95 case 's': 96 seed = atoi(&argp[2]); 97 seedSpec = 1; 98 break; 99 case 'h': 100 default: 101 usage(argv); 102 } 103 } 104 105 if(!seedSpec) { 106 unsigned long tim; 107 time(&tim); 108 seed = (unsigned)tim; 109 } 110 SRAND(seed); 111 112 /* 113 * Scratch digits, big enough for anything. Malloc here, init with 114 * random data before each test. 115 */ 116 digit1 = malloc(sizeof(giantDigit) * loops * 2); 117 digit2 = malloc(sizeof(giantDigit) * loops * 2); 118 119 /* vect1 and vect2 are arrays of giantDigit arrays */ 120 vect1 = malloc(sizeof(giantDigit) * loops * maxSize); 121 vect2 = malloc(sizeof(giantDigit) * loops * maxSize); 122 123 if((digit1 == NULL) || (digit1 == NULL) || 124 (vect1 == NULL) || (vect2 == NULL)) { 125 printf("malloc error\n"); 126 exit(1); 127 } 128 129 printf("Starting giantAsm test: seed %d\n", seed); 130 131 /* giantAddDigits test */ 132 randDigits(loops, digit1); 133 randDigits(loops, digit2); 134 dig1p = digit1; 135 dig2p = digit2; 136 PLAT_GET_TIME(startTime); 137 for(i=0; i<loops; i++) { 138 scr1 = giantAddDigits(*dig1p++, *dig2p++, &scr2); 139 } 140 PLAT_GET_TIME(endTime); 141 elapsed = PLAT_GET_NS(startTime, endTime); 142 printf("giantAddDigits: %f ns\n", 143 (double)elapsed / (double)loops); 144 145 /* giantAddDouble test */ 146 randDigits(loops, digit1); 147 randDigits(loops * 2, digit2); 148 dig1p = digit1; 149 dig2p = digit2; 150 PLAT_GET_TIME(startTime); 151 for(i=0; i<loops; i++) { 152 giantAddDouble(dig2p, dig2p+1, *dig1p++); 153 dig2p += 2; 154 } 155 PLAT_GET_TIME(endTime); 156 elapsed = PLAT_GET_NS(startTime, endTime); 157 printf("giantAddDouble: %f ns\n", 158 (double)elapsed / (double)loops); 159 160 /* giantSubDigits test */ 161 randDigits(loops, digit1); 162 randDigits(loops, digit2); 163 dig1p = digit1; 164 dig2p = digit2; 165 PLAT_GET_TIME(startTime); 166 for(i=0; i<loops; i++) { 167 scr1 = giantSubDigits(*dig1p++, *dig2p++, &scr2); 168 } 169 PLAT_GET_TIME(endTime); 170 elapsed = PLAT_GET_NS(startTime, endTime); 171 printf("giantSubDigits: %f ns\n", 172 (double)elapsed / (double)loops); 173 174 /* giantMulDigits test */ 175 randDigits(loops, digit1); 176 randDigits(loops, digit2); 177 dig1p = digit1; 178 dig2p = digit2; 179 PLAT_GET_TIME(startTime); 180 for(i=0; i<loops; i++) { 181 giantMulDigits(*dig1p++, *dig2p++, &scr1, &scr2); 182 } 183 PLAT_GET_TIME(endTime); 184 elapsed = PLAT_GET_NS(startTime, endTime); 185 printf("giantMulDigits: %f ns\n", 186 (double)elapsed / (double)loops); 187 188 printf("\nvectorMultiply:\n"); 189 for(numDigits=minSize; numDigits<=maxSize; numDigits*=2) { 190 191 randDigits(loops, digit1); // plierDigit 192 randDigits(loops * numDigits, vect1); // candVector 193 randDigits(loops * numDigits, vect2); // prodVector 194 dig1p = digit1; 195 vect1p = vect1; 196 vect2p = vect2; 197 198 PLAT_GET_TIME(startTime); 199 for(i=0; i<loops; i++) { 200 scr1 = VectorMultiply(*dig1p++, // plierDigit 201 vect1p, // candVector 202 numDigits, 203 vect2p); // prodVector 204 vect1p += numDigits; 205 vect2p += numDigits; 206 } 207 PLAT_GET_TIME(endTime); 208 elapsed = PLAT_GET_NS(startTime, endTime); 209 printf(" bits = %4d : %f ns\n", 210 numDigits * GIANT_BITS_PER_DIGIT, 211 (double)elapsed / (double)loops); 212 213 } /* for numDigits */ 214 return 0; 215} 216