- My tests show a 2x speedup for the case without forced branch mispredicts
- Merom Events of
BR_INST_RETIRED.ANY and BR_INST_RETIRED.MISPRED are measured to come out nearly identical to Netburst's Branches Retired and Mispredicted Brances Retired. See SEPCheatSheet
/* We will do 'ITERS' iterations per repetition, and then
* 'REPEAT' repetitions
*/
#define ITERS 1000
#define REPEAT 100000
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
double crunch_routine(long iters, long repeat, int* data)
{
long i, j;
/* volatile done so the compiler won't combine operations
* and so that icc won't throw out code (since the
* variables aren't used anywhere else)
*/
volatile float f = 0;
volatile int k = 0;
double total_time;
struct timeval start, end;
gettimeofday(&start, NULL);
for (j=0; j < repeat; j++)
for (i=0; i < iters; i++)
{
if (data[i] != 0)
{ f += (12345.67 + (float)i + (float)k);
}
else
{ k += (int)f + 12;
}
}
gettimeofday(&end, NULL);
total_time =
(end.tv_sec + (end.tv_usec * 0.000001)) -
(start.tv_sec + (start.tv_usec * 0.000001));
return total_time;
}
int main(int argc, char* argv[])
{
double time_mispredicted, time_predicted;
long i;
long branches_taken = 0;
int* data;
int temp;
int do_random = 1;
int do_predictable = 1;
printf("doing %d total iterations\n", ITERS*REPEAT);
if (argc > 1)
{ printf ("argv %s\n", argv[1]);
if (!strcmp(argv[1], "r"))
{ printf("doing random only\n");
do_predictable = 0;
}
else if (!strcmp(argv[1], "p"))
{ printf("doing predictable only\n");
do_random = 0;
}
}
data = (int *)malloc(sizeof(int)*ITERS);
/* 'data[]' contains elements to control the branch.
* - for the forced-mispredict case, we fill it with random values
* - for the forced-predictable case, we fill it with alternative values.
* this forces an even distribution for both cases
*/
if (do_random)
{ for (i=0; i < ITERS; i++)
{ data[i] = (rand()%2);
}
time_mispredicted = crunch_routine(ITERS, REPEAT, data);
printf("Mispredicted time: %f\n", time_mispredicted);
branches_taken += 1 + ITERS + (ITERS*REPEAT*2);
}
if (do_predictable)
{ for (i=0; i < ITERS; i++)
{ data[i] = i %2;
}
time_predicted = crunch_routine(ITERS, REPEAT, data);
printf("Predicted time: %f\n", time_predicted);
branches_taken += 1 + ITERS + (ITERS*REPEAT*2);
}
if (do_random && do_predictable)
printf("speedup: %f\n", time_mispredicted/time_predicted);
if (do_random)
{
printf("est. mispredicted branches: %ld\n", (long)ITERS*REPEAT/2);
}
printf("est. total branches: %ld\n", branches_taken);
free(data);
return 0;
}
--
MattWalsh - 21 Jun 2006