l1cachesize.c
来自「基于Blas CLapck的.用过的人知道是干啥的」· C语言 代码 · 共 299 行
C
299 行
/* * Automatically Tuned Linear Algebra Software v3.8.0 * (C) Copyright 1997 R. Clint Whaley * * 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 copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions, and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the ATLAS group or the names of its contributers may * not be used to endorse or promote products derived from this * software without specific written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 ATLAS GROUP OR ITS 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 <stdio.h>#include <stdlib.h>#define REPS 4096#ifndef time00 #define time00 ATL_cputime#endifdouble time00();// #define USE_OLD#ifdef USE_OLDint L1CacheSize_read(int MAXL1CACHE, double tol){ int ntests, h, i, j, k, reps=REPS*MAXL1CACHE, len, dlen, size=0; double *p, *d, *st; double t1, t2, *times; register double d0, d1, d2, d3; for (i=2, j=0; i <= MAXL1CACHE; i <<= 1, j++); times = malloc(j*sizeof(double)); ntests = j; h=0; for (i=2; i <= MAXL1CACHE; i <<= 1) { dlen = (i*1024+7) / sizeof(double); dlen = (dlen >> 3)<<3; len = dlen * 8; d = p = malloc(len); st = p + dlen; for (k=0; k != dlen; k += 8) { d[k] = 5.0; d[k+1] = -5.0; d[k+2] = -5.0; d[k+3] = 5.0; d[k+4] = -5.0; d[k+5] = 5.0; d[k+6] = 5.0; d[k+7] = -5.0; } d0 = d1 = d2 = d3 = 0.0; do { t1 = time00(); for (j=0; j != reps; j++) { do { d0 += *d; d1 += d[2]; d2 += d[4]; d3 += d[6]; d += 8; } while (d != st); d = p; } t1 = time00() - t1; if (t1 < 0.6 && h == 0) reps += reps; } while (t1 < 0.6 && h == 0); times[h] = t1; d0 += d1 + d2 + d3; if (d0 > 100.0) exit(-1); fprintf(stderr, " L1CS=%d, time=%f\n",i, times[h]); reps >>= 1; free(p); h++; }#ifdef RawSize t2 = 0.0; j = 0; for (i=1; i < ntests; i++) { t1 = times[i] - times[i-1]; if (t1 < 0) t1 = 0.0; if (t1 > t2) { t2 = t1; j=i; } }#else t2 = 1.0; j = 0; for (i=1; i < ntests; i++) /* find biggest % increase */ { t1 = times[i] / times[i-1]; if (t1 > t2) { t2 = t1; j=i; } }#endif fprintf(stderr, "\n"); if (tol != 0.0) { if (tol*times[j-1] > times[j]) { free(times); return(0); } } free(times); return(1 << j);}#elsevoid initmem(int n, double *mem)/* * Initialize mem to something that won't cause overlow, but confuse * things a little so compiler can't get rid of code */{ double d; int i; if (rand() > 27) d = ( 0.5 - ((double)rand())/((double)RAND_MAX) ); else d = ( 1.0 - ((double)rand())/((double)RAND_MAX) ); for (i=0; i < n; i++) mem[i] = ( 0.5 - ((double)rand())/((double)RAND_MAX) ); for (i=0; i < n; i += 8) { mem[i] = d; mem[i+2] = -d; mem[i+4] = -d; mem[i+6] = d; d = -d; }}int L1CacheSize_read(int MAXL1CACHE, double tol){ int ntests, h, i, j, k, reps=REPS*MAXL1CACHE, len, dlen, size=0; double *p, *d, *st; double t1, t2, *times; register double d0, d1, d2, d3; for (i=2, j=0; i <= MAXL1CACHE; i <<= 1, j++); times = malloc(j*sizeof(double)); ntests = j; h=0; for (i=2; i <= MAXL1CACHE; i <<= 1) { dlen = (i*1024+7) / sizeof(double); dlen = (dlen >> 3)<<3; len = dlen * 8; d = p = malloc(len); st = p + dlen; initmem(dlen, d); d0 = d1 = d2 = d3 = 0.0; do { t1 = time00(); for (j=0; j != reps; j++) { do { d0 += *d; d1 += d[2]; d2 += d[4]; d3 += d[6]; d += 8; } while (d != st); d = p; } t1 = time00() - t1; if (t1 < 0.6 && h == 0) reps += reps; } while (t1 < 0.6 && h == 0); times[h] = t1; d0 += d1 + d2 + d3; fprintf(stderr, " L1CS=%d, time=%f (ignore=%.1e)\n",i, times[h], d0); reps >>= 1; free(p); h++; }#ifdef RawSize t2 = 0.0; j = 0; for (i=1; i < ntests; i++) { t1 = times[i] - times[i-1]; if (t1 < 0) t1 = 0.0; if (t1 > t2) { t2 = t1; j=i; } }#else t2 = 1.0; j = 0; for (i=1; i < ntests; i++) /* find biggest % increase */ { t1 = times[i] / times[i-1]; if (t1 > t2) { t2 = t1; j=i; } }#endif fprintf(stderr, "\n"); if (tol != 0.0) { if (tol*times[j-1] > times[j]) { free(times); return(0); } } free(times); return(1 << j);}#endif#define BIGBOY 256#define L1CacheSize L1CacheSize_readint GetL1Size(int MaxSize, double tol){ int L1Size, tmp, correct=1; fprintf(stderr, "\n Calculating L1 cache size:\n"); L1Size = L1CacheSize(MaxSize, tol); if (L1Size == 0) tmp = -1.0; else { fprintf(stderr, " Confirming result of %dkb:\n", L1Size); tmp = L1CacheSize(MaxSize, 0.0); if (tmp == L1Size) tmp = L1CacheSize(MaxSize, 0.0); } if (tmp != L1Size && MaxSize < BIGBOY) { if (L1Size) fprintf(stderr, " L1 size not confirmed; trying large maximum size:\n"); else fprintf(stderr, " Timing differences below tolerance, trying larger maximum cache size:\n"); L1Size = L1CacheSize(BIGBOY, 0.0); fprintf(stderr, " Confirming result of %dkb:\n", L1Size); tmp = L1CacheSize(BIGBOY, 0.0); if (tmp == L1Size) tmp = L1CacheSize(BIGBOY, 0.0); } correct = (tmp == L1Size); fprintf(stderr, "Calculated L1 cache size = %dkb; Correct=%d\n", L1Size, correct); return (correct ? L1Size : 0);}main(int nargs, char *args[]){ int L1Size, MaxSize=64, correct=1; FILE *L1f; if (nargs > 2) { fprintf(stderr, "USAGE: %s <max L1 cache size (in kilobytes)>\n",args[0]); exit(-1); } if (nargs > 1) MaxSize = atoi(args[1]); L1Size = GetL1Size(MaxSize, 1.08); if (!L1Size) L1Size = GetL1Size(MaxSize, 1.08); if (!L1Size) { fprintf(stderr, "\nCan't detect the L1 cache; setting to 32KB.\n"); L1Size = 32; correct = 0; } fprintf(stderr, "Calculated L1 cache size = %dkb; Correct=%d\n", L1Size, correct); L1f = fopen("res/L1CacheSize", "w"); if (L1f) { fprintf(L1f, "%d\n",L1Size); fclose(L1f); exit(0); } exit(-1);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?