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);
}