12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241 |
- /*
- * Calibrator v0.9e
- * by Stefan.Manegold@cwi.nl, http://www.cwi.nl/~manegold/Calibrator/
- *
- * All rights reserved.
- * No warranties.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above notice, this list
- * of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above notice, this
- * list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by
- * Stefan.Manegold@cwi.nl, http://www.cwi.nl/~manegold/.
- * 4. Any publication of result obtained by use of this software must
- * display a reference as follows:
- * Results produced by Calibrator v0.9e
- * (Stefan.Manegold@cwi.nl, http://www.cwi.nl/~manegold/)
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS `AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
- /*
- #include <unistd.h>
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <string.h>
- #include <stdarg.h>
- #define VERSION "0.9e"
- #define NUMLOADS 100000
- #define REDUCE 10
- #define NUMTRIES 3
- #define MINRANGE 1024
- #define MAXLEVELS 9
- #define LENPLATEAU 3
- #define EPSILON1 0.1
- /* #define EPSILON3 2.0 */
- /* #define EPSILON2 0.04 */
- #define EPSILON4 1.0
- #define MIN(a,b) (a<b?a:b)
- #define MAX(a,b) (a>b?a:b)
- #define NOABS(x) ((dbl)x)
- #define FABS fabs
- #define lng long
- #define dbl float
- lng MINTIME = 10000;
- #ifdef WIN32
- #include <Windows.h>
- /* #define MINTIME 100000 */
- size_t getpagesize() { return 4096; }
- lng oldtp = 0;
- lng now(void)
- {
- lng tp = (lng)timeGetTime();
- if (oldtp == 0) {
- /* timeBeginPeriod(1); */
- tp += 11;
- while ((lng)timeGetTime() <= tp) ;
- oldtp = tp = (lng)timeGetTime();
- }
- return (lng)((tp - oldtp) * (lng)1000);
- }
- #else
- #include <sys/time.h>
- /* #define MINTIME 10000 */
- struct timeval oldtp = { 0 };
- lng now(void)
- {
- struct timeval tp;
- gettimeofday(&tp, 0);
- if (oldtp.tv_sec == 0 && oldtp.tv_usec == 0) {
- oldtp = tp;
- }
- return (lng)( (lng)(tp.tv_sec - oldtp.tv_sec ) * (lng)1000000 +
- (lng)(tp.tv_usec - oldtp.tv_usec) );
- }
- #endif
- void ErrXit(char *format, ...) {
- va_list ap;
- char s[1024];
- va_start(ap,format);
- vsprintf(s, format, ap);
- va_end(ap);
- fprintf(stderr, "\n! %s !\n", s);
- fflush(stderr);
- exit(1);
- }
- lng round(dbl x)
- {
- return (lng)(x + 0.5);
- }
- char last(char *s)
- {
- while (*s++);
- return (s[-2]);
- }
- lng bytes(char *s)
- {
- lng n = atoi(s);
- if ((last(s) == 'k') || (last(s) == 'K'))
- n *= 1024;
- if ((last(s) == 'm') || (last(s) == 'M'))
- n *= (1024 * 1024);
- if ((last(s) == 'g') || (last(s) == 'G'))
- n *= (1024 * 1024 * 1024);
- return (n);
- }
- #define NSperIt(t) (((dbl)(t)) / (((dbl)NUMLOADS) / 1000.0))
- #define CYperIt(t) (((dbl)((t) * MHz)) / ((dbl)NUMLOADS))
- long use_result_dummy; /* !static for optimizers. */
- void use_pointer(void *result) { use_result_dummy += (long)result; }
- lng loads(char *array, lng range, lng stride, lng MHz, FILE *fp, int delay)
- {
- register char **p = 0;
- lng i, j=1, tries;
- lng time, best = 2000000000;
- fprintf(stderr, "\r%11ld %11ld %11ld", range, stride, range/stride);
- fflush(stderr);
- /*
- for (i = stride; i < range; i += stride) {
- p = (char **)&array[i];
- *p = &array[i - stride];
- }
- p = (char **)&array[0];
- *p = &array[i - stride];
- */
- for (i = stride; i < range; i += stride);
- i -= stride;
- for (; i >= 0; i -= stride) {
- char *next;
- p = (char **)&array[i];
- if (i < stride) {
- next = &array[range - stride];
- } else {
- next = &array[i - stride];
- }
- *p = next;
- }
- #define ONE p = (char **)*p;
- #define TEN ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE
- #define HUNDRED TEN TEN TEN TEN TEN TEN TEN TEN TEN TEN
- /*
- #define THOUSAND HUNDRED HUNDRED HUNDRED HUNDRED HUNDRED \
- HUNDRED HUNDRED HUNDRED HUNDRED HUNDRED
- */
- #define FILL p++; p--; p++; p--; p++; p--; p++; p--; p++; p--;
- #define ONEx p = (char **)*p; \
- FILL FILL FILL FILL FILL FILL FILL FILL FILL FILL
- /*
- #define TENx ONEx ONEx ONEx ONEx ONEx ONEx ONEx ONEx ONEx ONEx
- #define HUNDREDx TENx TENx TENx TENx TENx TENx TENx TENx TENx TENx
- */
- if(delay) for (tries = 0; tries < NUMTRIES; ++tries) {
- i = (j * NUMLOADS) / REDUCE;
- time = now();
- while (i > 0) {
- ONEx
- i -= 1;
- }
- time = now() - time;
- use_pointer((void *)p);
- if (time <= MINTIME) {
- j *= 2;
- tries--;
- } else {
- time *= REDUCE;
- time /= j;
- if (time < best) {
- best = time;
- }
- }
- } else for (tries = 0; tries < NUMTRIES; ++tries) {
- i = (j * NUMLOADS);
- time = now();
- while (i > 0) {
- HUNDRED
- i -= 100;
- }
- time = now() - time;
- use_pointer((void *)p);
- if (time <= MINTIME) {
- j *= 2;
- tries--;
- } else {
- time /= j;
- if (time < best) {
- best = time;
- }
- }
- }
- fprintf(stderr, " %11ld %11ld", best*j, best);
- fflush(stderr);
- if (fp) {
- fprintf(fp, " %06ld %05.1f %05.1f"
- ,best /* elapsed time [microseconds] */
- ,NSperIt(best) /* nanoseconds per iteration */
- ,CYperIt(best) /* clocks per iteration */
- );
- fflush(fp);
- }
- return best;
- }
- lng** runCache(char *array, lng maxrange, lng minstride, lng MHz, FILE *fp, lng *maxstride)
- {
- lng i, r, x, y, z, range = maxrange, stride = minstride / 2;
- dbl f = 0.25;
- lng last, time = 0, **result;
- lng pgsz = getpagesize();
- int delay;
- if (*maxstride) {
- fprintf(stderr, "analyzing cache latency...\n");
- } else {
- fprintf(stderr, "analyzing cache throughput...\n");
- }
- fprintf(stderr, " range stride spots brutto- netto-time\n");
- fflush(stderr);
- if (!(*maxstride)) {
- do {
- stride *= 2;
- last = time;
- time = loads(array, range, stride, MHz, 0, 0);
- if (!time)
- ErrXit("runCache: 'loads(%x(array), %ld(range), %ld(stride), %ld(MHz), 0(fp), 0(delay))` returned elapsed time of 0us",
- array, range, stride, MHz);
- #ifdef EPSILON1
- } while (((fabs(time - last) / (dbl)time) > EPSILON1) && (stride <= (maxrange / 2)));
- #endif
- #ifdef EPSILON3
- } while ((fabs(CYperIt(time) - CYperIt(last)) > EPSILON3) && (stride <= (maxrange / 2)));
- #endif
- *maxstride = stride;
- delay = 0;
- } else if (*maxstride < 0) {
- *maxstride *= -1;
- delay = 0;
- } else {
- delay = 1;
- }
- for (r = MINRANGE, y = 1; r <= maxrange; r *= 2) {
- for (i = 3; i <= 5; i++) {
- range = r * f * i;
- if ((*maxstride <= range) && (range <= maxrange)) {
- for (stride = *maxstride, x = 1; stride >= minstride; stride /= 2, x++) {
- }
- y++;
- }
- }
- }
- if (!(result = (lng**)malloc(y * sizeof(lng*))))
- ErrXit("runCache: 'result = malloc(%ld)` failed", y * sizeof(lng*));
- for (z = 0; z < y; z++) {
- if (!(result[z] = (lng*)malloc(x * sizeof(lng))))
- ErrXit("runCache: 'result[%ld] = malloc(%ld)` failed", z, x * sizeof(lng));
- memset(result[z], 0, x * sizeof(lng));
- }
- result[0][0] = (y << 24) | x;
- fprintf(fp, "# Calibrator v%s\n", VERSION);
- fprintf(fp, "# (by Stefan.Manegold@cwi.nl, http://www.cwi.nl/~manegold/)\n");
- for (r = MINRANGE, y = 1; r <= maxrange; r *= 2) {
- for (i = 3; i <= 5; i++) {
- range = r * f * i;
- if ((*maxstride <= range) && (range <= maxrange)) {
- result[y][0] = range;
- fprintf(fp, "%08.1f %05ld"
- ,range / 1024.0 /* range in KB */
- ,range / pgsz /* # pages covered */
- );
- fflush(fp);
- for (stride = *maxstride, x = 1; stride >= minstride; stride /= 2, x++) {
- if (!result[0][x]) {
- result[0][x] = stride;
- }
- fprintf(fp, " %03ld %09ld %08.1f"
- ,stride /* stride */
- ,range / stride /* # spots accessed */
- ,((dbl)NUMLOADS) / ((dbl)(range / stride)) /* # accesses per spot */
- );
- fflush(fp);
- result[y][x] = loads(array, range, stride, MHz, fp, delay);
- }
- fprintf(fp, "\n");
- fflush(fp);
- y++;
- }
- }
- }
- fprintf(stderr, "\n\n");
- fflush(stderr);
- return result;
- }
- lng** runTLB(char *array, lng maxrange, lng minstride, lng shift, lng mincachelines, lng MHz, FILE *fp, lng *maxstride)
- {
- lng i, x, y, z, stride, minspots, maxspots, p;
- lng range = maxrange, s = minstride / 2, spots = mincachelines / 2;
- dbl f = 0.25;
- lng tmax, smin, xmin, last, time = 0, **result;
- lng pgsz = getpagesize();
- int delay;
- fprintf(stderr, "analyzing TLB latency...\n");
- fprintf(stderr, " range stride spots brutto- netto-time\n");
- fflush(stderr);
- if (!(*maxstride)) {
- do {
- s *= 2;
- stride = s + shift;
- range = stride * spots;
- last = time;
- time = loads(array, range, stride, MHz, 0, 0);
- if (!time)
- ErrXit("runTLB: 'loads(%x(array), %ld(range), %ld(stride), %ld(MHz), 0(fp), 0(delay))` returned elapsed time of 0us",
- array, range, stride, MHz);
- #ifdef EPSILON1
- } while ((((fabs(time - last) / (dbl)time) > EPSILON1) || (stride < (pgsz / 1))) && (range <= (maxrange / 2)));
- /* } while (((fabs(time - last) / (dbl)time) > EPSILON1) && (range <= (maxrange / 2))); */
- #endif
- #ifdef EPSILON3
- } while ((fabs(CYperIt(time) - CYperIt(last)) > EPSILON3) || (stride < (pgsz / 1))) && (range <= (maxrange / 2)));
- /* } while (fabs(CYperIt(time) - CYperIt(last)) > EPSILON3) && (range <= (maxrange / 2))); */
- #endif
- *maxstride = s;
- delay = 0;
- } else {
- delay = 1;
- }
- minspots = MAX(MINRANGE / (minstride + shift), 4);
- maxspots = maxrange / (*maxstride + shift);
- /* maxspots = mincachelines; */
- for (p = minspots, y = 2; p <= maxspots; p *= 2) {
- for (i = 3; i <= 5; i++) {
- spots = p * f * i;
- if ((spots * (*maxstride + shift)) <= maxrange) {
- for (s = *maxstride, x = 2; s >= minstride; s /= 2, x++) {
- }
- y++;
- }
- }
- }
- if (!(result = (lng**)malloc(y * sizeof(lng*))))
- ErrXit("runTLB: 'result = malloc(%ld)` failed", y * sizeof(lng*));
- for (z = 0; z < y; z++) {
- if (!(result[z] = (lng*)malloc(x * sizeof(lng))))
- ErrXit("runTLB: 'result[%ld] = malloc(%ld)` failed", z, x * sizeof(lng*));
- memset(result[z], 0, x * sizeof(lng));
- }
- result[0][0] = (y << 24) | x;
- fprintf(fp, "# Calibrator v%s\n", VERSION);
- fprintf(fp, "# (by Stefan.Manegold@cwi.nl, http://www.cwi.nl/~manegold/)\n");
- for (p = minspots, y = 2; p <= maxspots; p *= 2) {
- for (i = 3; i <= 5; i++) {
- spots = p * f * i;
- if ((spots * (*maxstride + shift)) <= maxrange) {
- result[y][0] = spots;
- fprintf(fp, "%09ld %08.1f"
- ,spots /* # spots accessed */
- ,((float)NUMLOADS) / ((float)spots) /* # accesses per spot */
- );
- fflush(fp);
- tmax = 0;
- smin = *maxstride + shift;
- xmin = 2;
- for (s = *maxstride, x = 2; s >= minstride; s /= 2, x++) {
- stride = s + shift;
- if (!result[0][x]) {
- result[0][x] = stride;
- }
- range = stride * spots;
- fprintf(fp, " %06ld %08.1f %05ld"
- ,stride /* stride */
- ,range / 1024.0 /* range in KB */
- ,range / pgsz /* # pages covered */
- );
- fflush(fp);
- result[y][x] = loads(array, range, stride, MHz, fp, delay);
- if (result[y][x] > tmax) {
- tmax = result[y][x];
- if (stride < smin) {
- smin = stride;
- xmin = x;
- }
- }
- }
- result[y][1] = tmax;
- result[1][xmin]++;
- fprintf(fp, "\n");
- fflush(fp);
- y++;
- }
- }
- }
- xmin = --x;
- for (--x; x >= 2; x--) {
- if (result[1][x] > result[1][xmin]) {
- xmin = x;
- }
- }
- result[0][1] = result[0][xmin];
- fprintf(stderr, "\n\n");
- fflush(stderr);
-
- return result;
- }
- typedef struct {
- lng levels;
- lng size[MAXLEVELS];
- lng linesize[MAXLEVELS];
- lng latency1[MAXLEVELS];
- lng latency2[MAXLEVELS];
- } cacheInfo;
- cacheInfo* analyzeCache(lng **result1, lng **result2, lng MHz)
- {
- lng x, y, xx, yy, range, lastrange, stride, level, a, l, n;
- lng last[LENPLATEAU], time1, time2, lasttime1, lasttime2;
- lng diff;
- cacheInfo *draft, *cache;
- if (!(draft = (cacheInfo*)malloc(4 * sizeof(cacheInfo))))
- ErrXit("analyzeCache: 'draft = malloc(%ld)` failed", 4 * sizeof(cacheInfo));
- if (!(cache = (cacheInfo*)malloc(sizeof(cacheInfo))))
- ErrXit("analyzeCache: 'cache = malloc(%ld)` failed", sizeof(cacheInfo));
- memset(draft, 0, 4 * sizeof(cacheInfo));
- memset(cache, 0, sizeof(cacheInfo));
-
- xx = (result1[0][0] & 0xffffff) - 1;
- yy = (result1[0][0] >> 24) - 1;
- level = 0;
- memset(last, 0, LENPLATEAU * sizeof(last[0]));
- a = LENPLATEAU;
- lastrange = 0;
- lasttime1 = 0;
- lasttime2 = 0;
- for (y = 1; y <= yy ; y++) {
- range = result1[y][0];
- for (x = 1; x <= xx; x++) {
- stride = result1[0][x];
- time1 = result1[y][x];
- time2 = result2[y][x];
- if (draft[1].linesize[level] && last[a] && (range == draft[1].size[level])) {
- #ifdef EPSILON1
- if ((fabs(time1 - last[a]) / (dbl)time1) < EPSILON1) {
- #endif
- #ifdef EPSILON3
- if (fabs(CYperIt(time1) - CYperIt(last[a])) < EPSILON3) {
- #endif
- draft[0].linesize[level] = stride;
- draft[1].linesize[level] = stride;
- }
- }
- if (draft[2].linesize[level] && last[0] && lastrange && (lastrange == draft[2].size[level])) {
- #ifdef EPSILON1
- if ((fabs(time1 - last[0]) / (dbl)time1) < EPSILON1) {
- #endif
- #ifdef EPSILON3
- if (fabs(CYperIt(time1) - CYperIt(last[0])) < EPSILON3) {
- #endif
- draft[2].linesize[level] = stride;
- draft[3].linesize[level] = stride;
- if (x == xx) {
- level++;
- memset(last, 0, LENPLATEAU * sizeof(last[0]));
- a = LENPLATEAU;
- }
- } else {
- level++;
- memset(last, 0, LENPLATEAU * sizeof(last[0]));
- a = LENPLATEAU;
- }
- }
- #ifdef EPSILON2
- if ((x == 1) && (!draft[2].linesize[level]) && ((last[0] && ((FABS(time1 - last[LENPLATEAU - 1]) / (dbl)last[LENPLATEAU - 1]) > EPSILON2)) || (y == yy))) {
- #endif
- #ifdef EPSILON4
- if ((x == 1) && (!draft[2].linesize[level]) && ((last[0] && (FABS(CYperIt(time1) - CYperIt(last[LENPLATEAU - 1])) >= EPSILON4)) || (y == yy))) {
- #endif
- draft[2].linesize[level] = draft[1].linesize[level];
- draft[2].size[level] = lastrange;
- draft[2].latency1[level] = lasttime1;
- draft[2].latency2[level] = lasttime2;
- draft[3].linesize[level] = stride;
- draft[3].size[level] = range;
- draft[3].latency1[level] = time1;
- draft[3].latency2[level] = time2;
- last[0] = time1;
- }
- if ((x == 1) && (a < LENPLATEAU) && (!last[0])) {
- #ifdef EPSILON2
- if ((FABS(time1 - last[LENPLATEAU - 1]) / (dbl)last[LENPLATEAU - 1]) < EPSILON2) {
- #endif
- #ifdef EPSILON4
- if (FABS(CYperIt(time1) - CYperIt(last[LENPLATEAU - 1])) <= EPSILON4) {
- #endif
- last[--a] = time1;
- } else {
- memset(last, 0, LENPLATEAU * sizeof(last[0]));
- a = LENPLATEAU;
- }
- }
- if ((x == 1) && (a == LENPLATEAU)) {
- last[--a] = time1;
- draft[0].linesize[level] = stride;
- draft[0].size[level] = lastrange;
- draft[0].latency1[level] = lasttime1;
- draft[0].latency2[level] = lasttime2;
- draft[1].linesize[level] = stride;
- draft[1].size[level] = range;
- draft[1].latency1[level] = time1;
- draft[1].latency2[level] = time2;
- }
- if (x == 1) {
- lasttime1 = time1;
- lasttime2 = time2;
- }
- }
- lastrange = range;
- }
- #ifdef DEBUG
- {
- lng ll;
- for (l = 0; l < level; l++) {
- for (ll = 0; ll < 4; ll++) {
- fprintf(stderr, "%2ld %5ld %3ld %05.1f %05.1f\n",
- l, draft[ll].size[l] / 1024, draft[ll].linesize[l], NSperIt(draft[ll].latency1[l]), CYperIt(draft[ll].latency1[l]));
- }
- fprintf(stderr, "\n");
- }
- fflush(stderr);
- }
- #endif
- for (l = n = 0 ; n < level; n++) {
- cache->latency1[l] = ((dbl)(draft[2].latency1[n] + draft[1].latency1[n]) / 2.0);
- cache->latency2[l] = ((dbl)(draft[2].latency2[n] + draft[1].latency2[n]) / 2.0);
- if ((l == 0) || ((log10(cache->latency1[l]) - log10(cache->latency1[l - 1])) > 0.3)) {
- cache->linesize[l] = draft[1].linesize[n];
- diff = -1;
- for (range = 1; range < result1[1][0]; range *= 2);
- for (y = 1; result1[y][0] < range; y++);
- if (l) {
- int yyy = 1;
- for (; y <= yy; y += yyy) {
- range = result1[y][0];
- if ((draft[2].size[n - 1] <= range) && (range < draft[1].size[n])) {
- if ((y > yyy) && (((result1[y][1]) - (result1[y - yyy][1])) > diff)) {
- diff = (result1[y][1]) - (result1[y - yyy][1]);
- cache->size[l - 1] = range;
- }
- if (((y + yyy) <= yy) && (((result1[y + yyy][1]) - (result1[y][1])) > diff)) {
- diff = (result1[y + yyy][1]) - (result1[y][1]);
- cache->size[l - 1] = range;
- }
- }
- }
- }
- l++;
- }
- }
- cache->size[--l] = draft[3].size[--n];
- cache->levels = l;
-
- #ifdef DEBUG
- for (l = 0; l <= cache->levels; l++) {
- fprintf(stderr, "%2ld %5ld %3ld %05.1f %05.1f\n",
- l, cache->size[l] / 1024, cache->linesize[l], NSperIt(cache->latency1[l]), CYperIt(cache->latency1[l]));
- }
- fprintf(stderr, "\n");
- fflush(stderr);
- #endif
- free(draft);
- draft = 0;
- return cache;
- }
- typedef struct {
- lng levels;
- lng shift;
- lng mincachelines;
- lng entries[MAXLEVELS];
- lng pagesize[MAXLEVELS];
- lng latency1[MAXLEVELS];
- lng latency2[MAXLEVELS];
- } TLBinfo;
- TLBinfo* analyzeTLB(lng **result1, lng **result2, lng shift, lng mincachelines, lng MHz)
- {
- lng x, y, xx, yy, spots, lastspots, stride, level, a, l, limit = 0, n;
- lng last[LENPLATEAU], time1, time2, lasttime1, lasttime2;
- dbl diff;
- TLBinfo *draft, *TLB;
- if (!(draft = (TLBinfo*)malloc(4 * sizeof(TLBinfo))))
- ErrXit("analyzeCache: 'draft = malloc(%ld)` failed", 4 * sizeof(TLBinfo));
- if (!(TLB = (TLBinfo*)malloc(sizeof(TLBinfo))))
- ErrXit("analyzeCache: 'TLB = malloc(%ld)` failed", sizeof(TLBinfo));
- memset(draft, 0, 4 * sizeof(TLBinfo));
- memset(TLB, 0, sizeof(TLBinfo));
- TLB->shift = shift;
- TLB->mincachelines = mincachelines;
-
- xx = (result1[0][0] & 0xffffff) - 1;
- yy = (result1[0][0] >> 24) - 1;
- level = 0;
- memset(last, 0, LENPLATEAU * sizeof(last[0]));
- a = LENPLATEAU;
- lastspots = 0;
- lasttime1 = 0;
- lasttime2 = 0;
- for (y = 2; !limit; y++) {
- spots = result1[y][0];
- limit = (y >= yy) || (spots >= (TLB->mincachelines * 1.25));
- for (x = 1; x <= xx; x++) {
- stride = result1[0][x];
- time1 = result1[y][x];
- time2 = result2[y][x];
- if (draft[1].pagesize[level] && last[a] && (spots == draft[1].entries[level])) {
- #ifdef EPSILON1
- if (((fabs(time1 - last[a]) / (dbl)time1) < EPSILON1) || (stride >= result1[0][1])) {
- #endif
- #ifdef EPSILON3
- if ((fabs(CYperIt(time1) - CYperIt(last[a])) < EPSILON3) || (stride >= result1[0][1])) {
- #endif
- draft[0].pagesize[level] = stride;
- draft[1].pagesize[level] = stride;
- }
- }
- if (draft[2].pagesize[level] && last[0] && lastspots && (lastspots == draft[2].entries[level])) {
- #ifdef EPSILON1
- if (((fabs(time1 - last[0]) / (dbl)time1) < EPSILON1) || (stride >= result1[0][1])) {
- #endif
- #ifdef EPSILON3
- if ((fabs(CYperIt(time1) - CYperIt(last[0])) < EPSILON3) || (stride >= result1[0][1])) {
- #endif
- draft[2].pagesize[level] = stride;
- draft[3].pagesize[level] = stride;
- if (x == xx) {
- level++;
- memset(last, 0, LENPLATEAU * sizeof(last[0]));
- a = LENPLATEAU;
- }
- } else {
- level++;
- memset(last, 0, LENPLATEAU * sizeof(last[0]));
- a = LENPLATEAU;
- }
- }
- #ifdef EPSILON2
- if ((x == 1) && (!draft[2].pagesize[level]) && ((last[0] && ((FABS(time1 - last[LENPLATEAU - 1]) / (dbl)last[LENPLATEAU - 1]) > EPSILON2)) || limit)) {
- #endif
- #ifdef EPSILON4
- if ((x == 1) && (!draft[2].pagesize[level]) && ((last[0] && (FABS(CYperIt(time1) - CYperIt(last[LENPLATEAU - 1])) >= EPSILON4)) || limit)) {
- #endif
- draft[2].pagesize[level] = draft[1].pagesize[level];
- draft[2].entries[level] = lastspots;
- draft[2].latency1[level] = lasttime1;
- draft[2].latency2[level] = lasttime2;
- draft[3].pagesize[level] = stride;
- draft[3].entries[level] = spots;
- draft[3].latency1[level] = time1;
- draft[3].latency2[level] = time2;
- last[0] = time1;
- }
- if ((x == 1) && (a < LENPLATEAU) && (!last[0])) {
- #ifdef EPSILON2
- if ((FABS(time1 - last[LENPLATEAU - 1]) / (dbl)last[LENPLATEAU - 1]) < EPSILON2) {
- #endif
- #ifdef EPSILON4
- if (FABS(CYperIt(time1) - CYperIt(last[LENPLATEAU - 1])) <= EPSILON4) {
- #endif
- last[--a] = time1;
- } else {
- memset(last, 0, LENPLATEAU * sizeof(last[0]));
- a = LENPLATEAU;
- }
- }
- if ((x == 1) && (a == LENPLATEAU)) {
- last[--a] = time1;
- draft[0].pagesize[level] = stride;
- draft[0].entries[level] = lastspots;
- draft[0].latency1[level] = lasttime1;
- draft[0].latency2[level] = lasttime2;
- draft[1].pagesize[level] = stride;
- draft[1].entries[level] = spots;
- draft[1].latency1[level] = time1;
- draft[1].latency2[level] = time2;
- }
- if (x == 1) {
- lasttime1 = time1;
- lasttime2 = time2;
- }
- }
- lastspots = spots;
- }
- #ifdef DEBUG
- {
- lng ll;
- for (l = 0; l < level; l++) {
- for (ll = 0; ll < 4; ll++) {
- fprintf(stderr, "%2ld %5ld %5ld %05.1f %05.1f\n",
- l, draft[ll].entries[l], draft[ll].pagesize[l], NSperIt(draft[ll].latency1[l]), CYperIt(draft[ll].latency1[l]));
- }
- fprintf(stderr, "\n");
- }
- fflush(stderr);
- }
- #endif
- for (l = n = 0; n < level; n++) {
- TLB->latency1[l] = ((dbl)(draft[2].latency1[n] + draft[1].latency1[n]) / 2.0);
- TLB->latency2[l] = ((dbl)(draft[2].latency2[n] + draft[1].latency2[n]) / 2.0);
- if ((l == 0) || (((log10(TLB->latency1[l]) - log10(TLB->latency1[l - 1])) > 0.3) && (draft[2].entries[l] > draft[1].entries[l]))) {
- TLB->pagesize[l] = draft[1].pagesize[n];
- diff = -1.0;
- for (spots = 1; spots < result1[2][0]; spots *= 2);
- for (y = 2; result1[y][0] < spots; y++);
- if (l) {
- int yyy = 1;
- for (; y <= yy; y += yyy) {
- spots = result1[y][0];
- if ((draft[2].entries[n - 1] <= spots) && (spots < draft[1].entries[n])) {
- if ((y > 4) && ((log(result1[y][1]) - log(result1[y - yyy][1])) > diff)) {
- diff = log(result1[y][1]) - log(result1[y - yyy][1]);
- TLB->entries[l - 1] = spots;
- }
- if (((y + yyy) <= yy) && ((log(result1[y + yyy][1]) - log(result1[y][1])) > diff)) {
- diff = log(result1[y + yyy][1]) - log(result1[y][1]);
- TLB->entries[l - 1] = spots;
- }
- }
- }
- }
- l++;
- }
- }
- TLB->entries[--l] = draft[3].entries[--n];
- TLB->levels = l;
-
- #ifdef DEBUG
- for (l = 0; l <= TLB->levels; l++) {
- fprintf(stderr, "%2ld %5ld %5ld %05.1f %05.1f\n",
- l, TLB->entries[l], TLB->pagesize[l], NSperIt(TLB->latency1[l]), CYperIt(TLB->latency1[l]));
- }
- fprintf(stderr, "\n");
- fflush(stderr);
- #endif
- free(draft);
- draft = 0;
- return TLB;
- }
- void plotCache(cacheInfo *cache, lng **result, lng MHz, char *fn, FILE *fp, lng delay)
- {
- lng l, x, xx = (result[0][0] & 0xffffff) - 1, y, yy = (result[0][0] >> 24) - 1;
- dbl xl, xh, yl, yh, z;
- char *s;
-
- xl = (dbl)result[1][0] / 1024.0;
- xh = (dbl)result[yy][0] / 1024.0;
- yl = 1.0;
- for (yh = 1000; yh < (lng)NSperIt(result[yy][1] - delay); yh *= 10);
- fprintf(fp, "# Calibrator v%s\n", VERSION);
- fprintf(fp, "# (by Stefan.Manegold@cwi.nl, http://www.cwi.nl/~manegold/)\n");
- fprintf(fp, " set term postscript portrait enhanced\n");
- fprintf(fp, " set output '%s.ps'\n", fn);
- fprintf(fp, "#set term gif transparent interlace small size 500, 707 # xFFFFFF x333333 x333333 x0055FF x005522 x660000 xFF0000 x00FF00 x0000FF\n");
- fprintf(fp, "#set output '%s.gif'\n", fn);
- fprintf(fp, "set data style linespoints\n");
- fprintf(fp, "set key below\n");
- fprintf(fp, "set title '%s'\n", fn);
- fprintf(fp, "set xlabel 'memory range [bytes]'\n");
- fprintf(fp, "set x2label ''\n");
- fprintf(fp, "set ylabel 'nanosecs per iteration'\n");
- fprintf(fp, "set y2label 'cycles per iteration'\n");
- fprintf(fp, "set logscale x 2\n");
- fprintf(fp, "set logscale x2 2\n");
- fprintf(fp, "set logscale y 10\n");
- fprintf(fp, "set logscale y2 10\n");
- fprintf(fp, "set format x '%%1.0f'\n");
- fprintf(fp, "set format x2 '%%1.0f'\n");
- fprintf(fp, "set format y '%%1.0f'\n");
- fprintf(fp, "set format y2 ''\n");
- fprintf(fp, "set xrange[%f:%f]\n", xl, xh);
- fprintf(fp, "#set x2range[%f:%f]\n", xl, xh);
- fprintf(fp, "set yrange[%f:%f]\n", yl, yh);
- fprintf(fp, "#set y2range[%f:%f]\n", yl, yh);
- fprintf(fp, "set grid x2tics\n");
- fprintf(fp, "set xtics mirror");
- for (x = 1, l = 1, s = " ("; x <= xh; x *= 2, l++, s = ", ") {
- if (l&1) {
- if (x >= (1024 * 1024)) {
- fprintf(fp, "%s'%ldG' %ld", s, x / (1024 * 1024), x);
- } else if (x >= 1024) {
- fprintf(fp, "%s'%ldM' %ld", s, x / 1024, x);
- } else {
- fprintf(fp, "%s'%ldk' %ld", s, x, x);
- }
- } else {
- fprintf(fp, "%s'' %ld", s, x);
- }
- }
- fprintf(fp, ")\n");
- fprintf(fp, "set x2tics mirror");
- for (l = 0, s = " ("; l < cache->levels; l++, s = ", ") {
- if (cache->size[l] >= (1024 * 1024 * 1024)) {
- fprintf(fp, "%s'[%ldG]' %ld", s, cache->size[l] / (1024 * 1024 * 1024), cache->size[l] / 1024);
- } else if (cache->size[l] >= (1024 * 1024)) {
- fprintf(fp, "%s'[%ldM]' %ld", s, cache->size[l] / (1024 * 1024), cache->size[l] / 1024);
- } else {
- fprintf(fp, "%s'[%ldk]' %ld", s, cache->size[l] / 1024, cache->size[l] / 1024);
- }
- }
- fprintf(fp, ")\n");
- fprintf(fp, "set y2tics");
- for (l = 0, s = " ("; l <= cache->levels; l++, s = ", ") {
- if (!delay) fprintf(fp, "%s'(%ld)' %f", s, round(CYperIt(cache->latency1[l] - delay)), NSperIt(cache->latency1[l] - delay));
- else fprintf(fp, "%s'(%ld)' %f", s, round(CYperIt(cache->latency2[l] - delay)), NSperIt(cache->latency2[l] - delay));
- }
- for (y = 1; y <= yh; y *= 10) {
- fprintf(fp, "%s'%1.3g' %ld", s, (dbl)(y * MHz) / 1000.0, y);
- }
- fprintf(fp, ")\n");
- for (l = 0; l <= cache->levels; l++) {
- if (!delay) z = (dbl)round(CYperIt(cache->latency1[l] - delay)) * 1000.0 / (dbl)MHz;
- else z = (dbl)round(CYperIt(cache->latency2[l] - delay)) * 1000.0 / (dbl)MHz;
- fprintf(fp, "set label %ld '(%1.3g) ' at %f,%f right\n", l + 1, z, xl, z);
- fprintf(fp, "set arrow %ld from %f,%f to %f,%f nohead lt 0\n", l + 1, xl, z, xh, z);
- }
- fprintf(fp, " set label %ld '^{ Calibrator v%s (Stefan.Manegold\\@cwi.nl, www.cwi.nl/~manegold) }' at graph 0.5,graph 0.02 center\n", l + 1, VERSION);
- fprintf(fp, "#set label %ld 'Calibrator v%s (Stefan.Manegold@cwi.nl, www.cwi.nl/~manegold)' at graph 0.5,graph 0.03 center\n", l + 1, VERSION);
- fprintf(fp, "plot \\\n0.1 title 'stride:' with points pt 0 ps 0");
- for (x = 1, l = cache->levels; x <= xx; x++) {
- fprintf(fp, " , \\\n'%s.data' using 1:($%ld-%f) title '", fn, (6 * x) + 1, NSperIt(delay));
- if ((l > 0) && (result[0][x] == cache->linesize[l])) {
- fprintf(fp, "\\{%ld\\}", result[0][x]);
- while ((--l >= 0) && (result[0][x] == cache->linesize[l]));
- } else {
- fprintf(fp, "%ld", result[0][x]);
- }
- fprintf(fp, "' with linespoints lt %ld pt %ld", x, x + 2);
- }
- fprintf(fp, "\n");
- fprintf(fp, "set nolabel\n");
- fprintf(fp, "set noarrow\n");
- fflush(fp);
- }
- void plotTLB(TLBinfo *TLB, lng **result, lng MHz, char *fn, FILE *fp, lng delay)
- {
- lng l, x, xx = (result[0][0] & 0xffffff) - 1, y, yy = (result[0][0] >> 24) - 1;
- dbl xl, xh, yl, yh, z;
- char *s;
-
- xl = (dbl)result[2][0];
- xh = (dbl)result[yy][0];
- yl = 1.0;
- for (yh = 1000; yh < (lng)NSperIt(result[yy][2] - delay); yh *= 10);
- fprintf(fp, "# Calibrator v%s\n", VERSION);
- fprintf(fp, "# (by Stefan.Manegold@cwi.nl, http://www.cwi.nl/~manegold/)\n");
- fprintf(fp, " set term postscript portrait enhanced\n");
- fprintf(fp, " set output '%s.ps'\n", fn);
- fprintf(fp, "#set term gif transparent interlace small size 500, 707 # xFFFFFF x333333 x333333 x0055FF x005522 x660000 xFF0000 x00FF00 x0000FF\n");
- fprintf(fp, "#set output '%s.gif'\n", fn);
- fprintf(fp, "set data style linespoints\n");
- fprintf(fp, "set key below\n");
- fprintf(fp, "set title '%s'\n", fn);
- fprintf(fp, "set xlabel 'spots accessed'\n");
- fprintf(fp, "set x2label ''\n");
- fprintf(fp, "set ylabel 'nanosecs per iteration'\n");
- fprintf(fp, "set y2label 'cycles per iteration'\n");
- fprintf(fp, "set logscale x 2\n");
- fprintf(fp, "set logscale x2 2\n");
- fprintf(fp, "set logscale y 10\n");
- fprintf(fp, "set logscale y2 10\n");
- fprintf(fp, "set format x '%%1.0f'\n");
- fprintf(fp, "set format x2 '%%1.0f'\n");
- fprintf(fp, "set format y '%%1.0f'\n");
- fprintf(fp, "set format y2 ''\n");
- fprintf(fp, "set xrange[%f:%f]\n", xl, xh);
- fprintf(fp, "#set x2range[%f:%f]\n", xl, xh);
- fprintf(fp, "set yrange[%f:%f]\n", yl, yh);
- fprintf(fp, "#set y2range[%f:%f]\n", yl, yh);
- fprintf(fp, "set grid x2tics\n");
- fprintf(fp, "set xtics mirror");
- for (x = 1, l = 1, s = " ("; x <= xh; x *= 2, l++, s = ", ") {
- if (l | 1) {
- if (x >= (1024 * 1024)) {
- fprintf(fp, "%s'%ldM' %ld", s, x / (1024 * 1024), x);
- } else if (x >= 1024) {
- fprintf(fp, "%s'%ldk' %ld", s, x / 1024, x);
- } else {
- fprintf(fp, "%s'%ld' %ld", s, x, x);
- }
- } else {
- fprintf(fp, "%s'' %ld", s, x);
- }
- }
- fprintf(fp, ")\n");
- fprintf(fp, "set x2tics mirror");
- for (l = 0, s = " ("; l < TLB->levels; l++, s = ", ") {
- if (TLB->entries[l] >= (1024 * 1024)) {
- fprintf(fp, "%s'[%ldM]' %ld", s, TLB->entries[l] / (1024 * 1024), TLB->entries[l]);
- } else if (TLB->entries[l] >= 1024) {
- fprintf(fp, "%s'[%ldk]' %ld", s, TLB->entries[l] / 1024, TLB->entries[l]);
- } else {
- fprintf(fp, "%s'[%ld]' %ld", s, TLB->entries[l], TLB->entries[l]);
- }
- }
- fprintf(fp, "%s'<L1>' %ld)\n", s, TLB->mincachelines);
- fprintf(fp, "set y2tics");
- for (l = 0, s = " ("; l <= TLB->levels; l++, s = ", ") {
- if (!delay) fprintf(fp, "%s'(%ld)' %f", s, round(CYperIt(TLB->latency1[l] - delay)), NSperIt(TLB->latency1[l] - delay));
- else fprintf(fp, "%s'(%ld)' %f", s, round(CYperIt(TLB->latency2[l] - delay)), NSperIt(TLB->latency2[l] - delay));
- }
- for (y = 1; y <= yh; y *= 10) {
- fprintf(fp, "%s'%1.3g' %ld", s, (dbl)(y * MHz) / 1000.0, y);
- }
- fprintf(fp, ")\n");
- for (l = 0; l <= TLB->levels; l++) {
- if (!delay) z = (dbl)round(CYperIt(TLB->latency1[l] - delay)) * 1000.0 / (dbl)MHz;
- else z = (dbl)round(CYperIt(TLB->latency2[l] - delay)) * 1000.0 / (dbl)MHz;
- fprintf(fp, "set label %ld '(%1.3g) ' at %f,%f right\n", l + 1, z, xl, z);
- fprintf(fp, "set arrow %ld from %f,%f to %f,%f nohead lt 0\n", l + 1, xl, z, xh, z);
- }
- fprintf(fp, " set label %ld '^{ Calibrator v%s (Stefan.Manegold\\@cwi.nl, www.cwi.nl/~manegold) }' at graph 0.5,graph 0.02 center\n", l + 1, VERSION);
- fprintf(fp, "#set label %ld 'Calibrator v%s (Stefan.Manegold@cwi.nl, www.cwi.nl/~manegold)' at graph 0.5,graph 0.03 center\n", l + 1, VERSION);
- fprintf(fp, "plot \\\n0.1 title 'stride:' with points pt 0 ps 0");
- for (x = 2, l = TLB->levels; x <= xx; x++) {
- fprintf(fp, " , \\\n'%s.data' using 1:($%ld-%f) title '", fn, (6 * (x - 1)) + 1, NSperIt(delay));
- if ((l > 0) && (result[0][x] == TLB->pagesize[l])) {
- fprintf(fp, "\\{%ld\\}", result[0][x]);
- while ((--l >= 0) && (result[0][x] == TLB->pagesize[l]));
- } else {
- fprintf(fp, "%ld", result[0][x]);
- }
- fprintf(fp, "' with linespoints lt %ld pt %ld", x, x + 2);
- }
- fprintf(fp, "\n");
- fprintf(fp, "set nolabel\n");
- fprintf(fp, "set noarrow\n");
- fflush(fp);
- }
- void printCPU(cacheInfo *cache, lng MHz, lng delay)
- {
- FILE *fp = stdout;
-
- fprintf(fp, "CPU loop + L1 access: ");
- fprintf(fp, " %6.2f ns = %3ld cy\n", NSperIt(cache->latency1[0]), round(CYperIt(cache->latency1[0])));
- fprintf(fp, " ( delay: ");
- fprintf(fp, " %6.2f ns = %3ld cy )\n", NSperIt(delay), round(CYperIt(delay)));
- fprintf(fp, "\n");
- fflush(fp);
- }
- void printCache(cacheInfo *cache, lng MHz)
- {
- lng l;
- FILE *fp = stdout;
-
- fprintf(fp, "caches:\n");
- fprintf(fp, "level size linesize miss-latency replace-time\n");
- for (l = 0; l < cache->levels; l++) {
- fprintf(fp, " %1ld ", l+1);
- if (cache->size[l] >= (1024 * 1024 * 1024)) {
- fprintf(fp, " %3ld GB ", cache->size[l] / (1024 * 1024 * 1024));
- } else if (cache->size[l] >= (1024 * 1024)) {
- fprintf(fp, " %3ld MB ", cache->size[l] / (1024 * 1024));
- } else {
- fprintf(fp, " %3ld KB ", cache->size[l] / 1024);
- }
- fprintf(fp, " %3ld bytes ", cache->linesize[l + 1]);
- fprintf(fp, " %6.2f ns = %3ld cy " , NSperIt(cache->latency2[l + 1] - cache->latency2[l]), round(CYperIt(cache->latency2[l + 1] - cache->latency2[l])));
- fprintf(fp, " %6.2f ns = %3ld cy\n", NSperIt(cache->latency1[l + 1] - cache->latency1[l]), round(CYperIt(cache->latency1[l + 1] - cache->latency1[l])));
- }
- fprintf(fp, "\n");
- fflush(fp);
- }
- void printTLB(TLBinfo *TLB, lng MHz)
- {
- lng l;
- FILE *fp = stdout;
-
- fprintf(fp, "TLBs:\n");
- fprintf(fp, "level #entries pagesize miss-latency");
- /*
- fprintf(fp, " replace-time");
- */
- fprintf(fp, "\n");
- for (l = 0; l < TLB->levels; l++) {
- fprintf(fp, " %1ld ", l+1);
- fprintf(fp, " %3ld ", TLB->entries[l]);
- if (TLB->pagesize[l + 1] >= (1024 * 1024 * 1024)) {
- fprintf(fp, " %3ld GB ", TLB->pagesize[l + 1] / (1024 * 1024 * 1024));
- } else if (TLB->pagesize[l + 1] >= (1024 * 1024)) {
- fprintf(fp, " %3ld MB ", TLB->pagesize[l + 1] / (1024 * 1024));
- } else {
- fprintf(fp, " %3ld KB ", TLB->pagesize[l + 1] / 1024);
- }
- fprintf(fp, " %6.2f ns = %3ld cy ", NSperIt(TLB->latency2[l + 1] - TLB->latency2[l]), round(CYperIt(TLB->latency2[l + 1] - TLB->latency2[l])));
- /*
- fprintf(fp, " %6.2f ns = %3ld cy" , NSperIt(TLB->latency1[l + 1] - TLB->latency1[l]), round(CYperIt(TLB->latency1[l + 1] - TLB->latency1[l])));
- */
- fprintf(fp, "\n");
- }
- fprintf(fp, "\n");
- fflush(fp);
- }
- lng getMINTIME () {
- lng t0=0, t1=0;
- t0=t1=now();
- while(t0==t1){
- t1=now();
- }
- return (t1-t0);
- }
- int main(int ac, char **av)
- {
- lng MHz, maxrange, mincachelines, maxlinesize, minstride = (lng)sizeof(char*), yy, y;
- lng maxCstride=0, maxTstride=0, delayC, delayT;
- char *array0, *array, fnn1[1024], fnx1[1024], fnn2[1024], fnx2[1024];
- FILE *fp;
- lng **result1, **result2;
- cacheInfo *cache;
- TLBinfo *TLB;
- lng align = 0, pgsz = getpagesize();
- fprintf(stdout,"\nCalibrator v%s\n(by Stefan.Manegold@cwi.nl, http://www.cwi.nl/~manegold/)\n", VERSION);
- if (ac < 4) ErrXit("usage: '%s <MHz> <size>[k|M|G] <filename>`", av[0]);
- MHz = atoi(av[1]);
- maxrange = bytes(av[2]) * 1.25;
- if (ac > 4) align = atoi(av[4]) % pgsz;
- if (ac > 5) maxCstride = -1 * abs(atoi(av[5]));
- if (!(array0 = (char *)malloc(maxrange+pgsz)))
- ErrXit("main: 'array0 = malloc(%ld)` failed", maxrange+pgsz);
- array = array0;
- fprintf(stderr,"%x %ld %ld %5ld\n",array,(lng)array,pgsz,(lng)array%pgsz);
- while (((lng)array % pgsz) != align) {
- fprintf(stderr,"\r%x %ld %ld %5ld",array,(lng)array,pgsz,(lng)array%pgsz);
- fflush(stderr);
- array++;
- }
- fprintf(stderr,"\n%x %ld %ld %5ld\n\n",array,(lng)array,pgsz,(lng)array%pgsz);
- fflush(stderr);
-
- MINTIME = MAX( MINTIME, 10*getMINTIME() );
- fprintf(stderr,"MINTIME = %ld\n\n",MINTIME);
- fflush(stderr);
- sprintf(fnn1, "%s.cache-replace-time", av[3]);
- sprintf(fnx1, "%s.data", fnn1);
- if (!(fp = fopen(fnx1,"w"))) ErrXit("main: 'fp = fopen(%s,\"w\")` failed", fnx1);
- result1 = runCache(array, maxrange, minstride, MHz, fp, &maxCstride);
- fclose(fp);
- sprintf(fnn2, "%s.cache-miss-latency", av[3]);
- sprintf(fnx2, "%s.data", fnn2);
- if (!(fp = fopen(fnx2,"w"))) ErrXit("main: 'fp = fopen(%s,\"w\")` failed", fnx2);
- result2 = runCache(array, maxrange, minstride, MHz, fp, &maxCstride);
- fclose(fp);
- cache = analyzeCache(result1, result2, MHz);
- mincachelines = ( cache->size[0] && cache->linesize[1] ? cache->size[0] / cache->linesize[1] : 1024 );
- maxlinesize = ( cache->linesize[cache->levels] ? cache->linesize[cache->levels] : maxCstride / 2 );
- delayC = cache->latency2[0] - cache->latency1[0];
- sprintf(fnx1, "%s.gp", fnn1);
- if (!(fp = fopen(fnx1,"w"))) ErrXit("main: 'fp = fopen(%s,\"w\")` failed", fnx1);
- plotCache(cache, result1, MHz, fnn1, fp, 0);
- fclose(fp);
- sprintf(fnx2, "%s.gp", fnn2);
- if (!(fp = fopen(fnx2,"w"))) ErrXit("main: 'fp = fopen(%s,\"w\")` failed", fnx2);
- plotCache(cache, result2, MHz, fnn2, fp, delayC);
- fclose(fp);
- yy = (result1[0][0] >> 24) - 1;
- for (y = 0; y <= yy; y++) {
- free(result1[y]);
- result1[y] = 0;
- }
- free(result1);
- result1 = 0;
- yy = (result2[0][0] >> 24) - 1;
- for (y = 0; y <= yy; y++) {
- free(result2[y]);
- result2[y] = 0;
- }
- free(result2);
- result2 = 0;
- sprintf(fnn1, "%s.TLB-miss-latency", av[3]);
- sprintf(fnx1, "%s.data", fnn1);
- if (!(fp = fopen(fnx1,"w"))) ErrXit("main: 'fp = fopen(%s,\"w\")` failed", fnx1);
- result1 = runTLB(array, maxrange, 1024, maxlinesize, mincachelines, MHz, fp, &maxTstride);
- fclose(fp);
- /*
- sprintf(fnn2, "%s.TLB2", av[3]);
- sprintf(fnx2, "%s.data", fnn2);
- if (!(fp = fopen(fnx2,"w"))) ErrXit("main: 'fp = fopen(%s,\"w\")` failed", fnx2);
- result2 = runTLB(array, maxrange, 1024, maxlinesize, mincachelines, MHz, fp, &maxTstride);
- fclose(fp);
- */
- result2 = result1;
- TLB = analyzeTLB(result1, result2, maxlinesize, mincachelines, MHz);
- delayT = TLB->latency2[0] - TLB->latency1[0];
- sprintf(fnx1, "%s.gp", fnn1);
- if (!(fp = fopen(fnx1,"w"))) ErrXit("main: 'fp = fopen(%s,\"w\")` failed", fnx1);
- plotTLB(TLB, result1, MHz, fnn1, fp, 0);
- fclose(fp);
- /*
- sprintf(fnx2, "%s.gp", fnn2);
- if (!(fp = fopen(fnx2,"w"))) ErrXit("main: 'fp = fopen(%s,\"w\")` failed", fnx2);
- plotTLB(TLB, result2, MHz, fnn2, fp, delayT);
- fclose(fp);
- */
- yy = (result1[0][0] >> 24) - 1;
- for (y = 0; y <= yy; y++) {
- free(result1[y]);
- result1[y] = 0;
- }
- free(result1);
- result1 = 0;
- /*
- yy = (result2[0][0] >> 24) - 1;
- for (y = 0; y <= yy; y++) {
- free(result2[y]);
- result2[y] = 0;
- }
- free(result2);
- */
- result2 = 0;
- fprintf(stdout,"\n");
- printCPU(cache, MHz, delayC);
- printCache(cache, MHz);
- printTLB(TLB, MHz);
- free(cache);
- cache = 0;
- free(TLB);
- TLB = 0;
- return(0);
- }
|