Daily Archives: November 17, 2016

Benchmark Generation 2 i5 -vs- Generation 3 i5

Once and a while I will benchmark a PC that I happen to get my hands on. I tested a laptop with a Gen 3 i5 and compared it to my desktop with has 2 Gen 2 i5….

erick@OptiPlex-790 ~/factor $ tail i5-3340M@3200Mhz-bmark.txt

Calculations Completed!
 Time: 9 seconds

Factor: Finished in about 10.000000 seconds.
 Pi: Finished in about 9.000000 seconds.

Factor to Pi Ratio 1.111111
 erick@OptiPlex-790 ~/factor $ tail i5-2500@3700.txt

Calculations Completed!
 Time: 9 seconds

Factor: Finished in about 10.000000 seconds.
 Pi: Finished in about 9.000000 seconds.

Factor to Pi Ratio 1.111111

It looks like a Generation 2 i5 running at 3700MHz can run calculations at the same rate as a Generation 3 i5 at 3200MHz. The benchmark is both a pi calculation and a factoring calculation. The ratios will vary from processor to processor sometimes. Especially across old -vs- new ones. But these seem to line up.

Comparison

It looks like the raw speed difference for a given clock speed, 3700/3200 = 1.15625x faster. In other words, the Gen 2 has to be running 1.15625x faster on the clock to get the same speeds.

Note: The MHz values are running one core at turbo speed.

Code

The code is something that I patched together. I wrote the factoring part years ago to run under MS-DOS and ported it to compile under GCC. I made it at a time that I was toying around with extracting factors of numbers and was an exercise in making speed efficient code. I always had some spare moments while waiting for other compiles to happen. At the time I was working on embedded code in industry, these compiles could take a few minutes with each change and up to 20 minutes when doing a scratch build. This is on machines of the Pentium 2 -4 era. When writing embedded code and compiling there were plenty of slices of time to experiment with other code.

The Pi part I snagged off the web a long time ago, not sure where, or I would reference it here. It is interesting to see how the speeds will vary between the Pi and Factor parts, therefore I compute a ratio of them. I fiddled with the constants so that the time that both parts run is about 10 seconds and around a 1:1 ratio on my current desktop i5@3300Mhz. Essentially the desktop is the reference normal against which I am comparing other machines.

 

 

#include <stdio.h> 
#include <float.h> 
#include <time.h> 
#include <stdlib.h> 
#include <sys/time.h> 
#include <unistd.h> 
 
 
    unsigned int x; 
unsigned int f = 0, stopn = 100000, maxFactor = 0; //4294967295 
   time_t curtime; 
 
     
    FILE *fp; 
 
 
long secstart, usecstart; 
long kf, ks; 
long *mf, *ms; 
long cnt, n, temp, nd; 
long i; 
long col, col1; 
long loc, stor[40]; 
 
int main(void) 
{ 
 
  float factor_time; 
  float pi_time; 
  float ratio; 
  factor_time = factor(); 
  pi_time = pi(); 
 
  ratio = factor_time / pi_time; 
   printf("\n\nFactor: Finished in about %f seconds. \n", factor_time); 
   printf("Pi: Finished in about %f seconds. \n", pi_time); 
 
   printf("\n\nFactor to Pi Ratio %f \n",ratio ); 
 
} 
 
 
int factor(void) 
{ 
    unsigned int i = 1; 
    unsigned int n; 
 
    time_t start, stop; 
    clock_t ticks; long count; 
 
     
    //scanf("%s",fname); 
    //scanf("%i",stopn); 
    //fopen("temp.txt","w"); 
    //stopn = argv[i]; 
 
 
    // Mark off the start time for the program.  
   time(&start); 
 
    for(n = 1;n < stopn;n++) 
    { 
        
    #if 1 
      // Inner loop, Walk through all values of numbers up to 1 more than the middle number. 
        for(x = 2;x < (n/2)+1;x++) 
        { 
          // Found a factor incriment f 
      //      if((n/x) - (int)(n/x) == 0) 
      if(n%x == 0) 
            { 
                f++; 
            } 
        } 
    #endif 
 
        //fprintf(fp,"%i    %i \n",n,f); 
    // If the value of the factor f is larger than the largest factor found, mark the occurance. 
    if(f > maxFactor) 
    { 
      printf("%i\t %i\t",n,f); 
 
      maxFactor = f; 
 
      // Get Current Time, print it out. 
      time(&curtime); 
      printf("%s", ctime(&curtime)); 
 
    } 
        // Reset the factor count for the next outer loop. 
        f = 0; 
        
    } 
 
    // Mark the stop time of the program. 
 
   time(&stop); 
    
   // How long did the program run and how much CPU time did it use. 
   //   printf("Used %0.2f seconds of CPU time. \n", (double)ticks/CLOCKS_PER_SEC); 
   printf("Finished in about %.0f seconds. \n", difftime(stop, start)); 
 
    return(difftime(stop, start)); 
} 
 
 
 
 
 
 
 
 
 
 
void shift(long *l1, long *l2, long lp, long lmod) 
{ 
    long k; 
 
    k = ((*l2) > 0 ? (*l2) / lmod: -(-(*l2) / lmod) - 1); 
    *l2 -= k * lmod; 
    *l1 += k * lp; 
} 
 
void yprint(long m) 
{ 
    if (cnt<n) 
    { 
        if (++col == 11) 
        { 
            col = 1; 
            if (++col1 == 6) 
                { 
                    col1 = 0; 
                    printf("\n"); 
                    printf("%4ld",m%10); 
                } 
            else printf("%3ld",m%10); 
        } 
        else printf("%ld",m); 
        cnt++; 
    } 
} 
 
void xprint(long m) 
{ 
    long ii, wk, wk1; 
 
    if (m < 8) 
    { 
        for (ii = 1; ii <= loc; ) 
        yprint(stor[(int)(ii++)]); 
        loc = 0; 
    } 
    else 
    { 
        if (m > 9) 
        { 
            wk = m / 10; 
            m %= 10; 
            for (wk1 = loc; wk1 >= 1; wk1--) 
            { 
                wk += stor[(int)wk1]; 
                stor[(int)wk1] = wk % 10; 
                wk /= 10; 
            } 
        } 
    } 
    stor[(int)(++loc)] = m; 
} 
 
void memerr(int errno) 
{ 
    printf("\a\nOut of memory error #%d\n", errno); 
    if (2 == errno) 
    free(mf); 
    _exit(2); 
} 
 
int pi(void) 
{ 
    int i=0; 
    char *endp; 
 
 
    stor[i++] = 0; 
 
    n = 22000; 
 
    mf = malloc((size_t)(n + 3L)*(size_t)sizeof(long)); 
    if (!mf) 
    memerr(1); 
    ms = malloc((size_t)(n + 3L)*(size_t)sizeof(long)); 
    if (!ms) 
    memerr(2); 
    printf("\nApproximation of PI to %ld digits\n", (long)n); 
 
    struct timeval tv; 
    struct timezone tz; 
        gettimeofday(&tv, &tz); 
        secstart=tv.tv_sec; 
        usecstart=tv.tv_usec; 
    cnt = 0; 
    kf = 25; 
    ks = 57121L; 
    mf[1] = 1L; 
    for (i = 2; i <= (int)n; i += 2) 
    { 
        mf[i] = -16L; 
        mf[i+1] = 16L; 
    } 
    for (i = 1; i <= (int)n; i += 2) 
    { 
        ms[i] = -4L; 
        ms[i+1] = 4L; 
    } 
    printf("\n 3."); 
    while (cnt < n) 
    { 
        for (i = 0; ++i <= (int)n - (int)cnt; ) 
        { 
            mf[i] *= 10L; 
            ms[i] *= 10L; 
        } 
        for (i =(int)(n - cnt + 1); --i >= 2; ) 
        { 
            temp = 2 * i - 1; 
            shift(&mf[i - 1], &mf[i], temp - 2, temp * kf); 
            shift(&ms[i - 1], &ms[i], temp - 2, temp * ks); 
        } 
        nd = 0; 
        shift((long *)&nd, &mf[1], 1L, 5L); 
        shift((long *)&nd, &ms[1], 1L, 239L); 
        xprint(nd); 
    } 
    printf("\n\nCalculations Completed!\n"); 
    gettimeofday(&tv, &tz); 
    printf("Time: %ld seconds\n",tv.tv_sec-secstart); 
    free(ms); 
    free(mf); 
    return(tv.tv_sec-secstart); 
}