Skip to content

Instantly share code, notes, and snippets.

@Sam-Belliveau
Last active October 21, 2018 15:44
Show Gist options
  • Select an option

  • Save Sam-Belliveau/8c61ddcbcf03985ae62cfa122bff5a13 to your computer and use it in GitHub Desktop.

Select an option

Save Sam-Belliveau/8c61ddcbcf03985ae62cfa122bff5a13 to your computer and use it in GitHub Desktop.
This is a timer that times in clock cycles. It uses __rdtscp(). It only workes on unix. I will not port it to windows as i dont think an application like this would make much use there. You can port it easily.
/*** PRINTING STUFF ***/
#include <stdio.h> /* printf() */
#include <stdlib.h> /* system() */
#include <stdint.h> /* fixed width ints */
/*** UNIX STUFF ***/
#include <x86intrin.h> /* __rdtscp() */
#include <unistd.h> /* sleep() */
#define SHOW_CPUID 0 /* True/False */
#define GET_TSC_PER_SEC 1 /* True/False */
#define TSC_WAIT_TIME 2 /* Seconds */
uint64_t tscPerSecond()
{
uint64_t start, end; /* Start/End Variables */
uint32_t dummy[4]; /* Dummy to pass for CPUID */
/* Record Sleep Function */
start = __rdtscp(dummy);
/* Sleep has an error width of */
/* around 1ms, which is fine */
sleep(TSC_WAIT_TIME);
/* Record End Time */
end = __rdtscp(dummy);
/* Return Ticks elapsed in a Second */
return (end - start) / TSC_WAIT_TIME;
}
int main(int argc, char** argv)
{
uint64_t start, end; /* Start/End Variables */
uint32_t scpu[4], ecpu[4]; /* CPU Information Gathering */
/* CPUID Prevents Out Of Order Execution */
/* Get start time / CPU information */
start = __rdtscp(scpu);
/* Run Specify Information */
for(int i = 1; i < argc; ++i)
system(argv[i]);
/* Get end time / CPU information */
end = __rdtscp(ecpu);
/* Make Space */
printf("\n");
/* Used if you want to show CPUID */
/* Mainly here to prevent CPUID, */
/* from getting optimized away */
if(SHOW_CPUID)
{
printf("+--------- STARTING CPUID ---------+\n");
printf("| EAX: 0x%08x | EBX: 0x%08x |\n", scpu[0], scpu[1]);
printf("| ECX: 0x%08x | EDX: 0x%08x |\n", scpu[2], scpu[3]);
printf("+-----------------------------------+\n\n");
printf("+---------- ENDING CPUID ----------+\n");
printf("| EAX: 0x%08x | EBX: 0x%08x |\n", ecpu[0], ecpu[1]);
printf("| ECX: 0x%08x | EDX: 0x%08x |\n", ecpu[2], ecpu[3]);
printf("+-----------------------------------+\n\n");
}
/* Get Cycles */
const uint64_t pTime = end - start; // Get overall time
printf("Execution Cycles: %lu ticks\n", pTime);
if(GET_TSC_PER_SEC)
{
/* Get Cycle Speed */
printf("Calculating Clock Speed... (etc=%is)\r", TSC_WAIT_TIME);
fflush(stdout);
const uint64_t CPS = tscPerSecond();
if(CPS > 100000)
if(CPS > 100000000)
if(CPS > 100000000000)
printf("Cycles Per Second: %luGHz", CPS/1000000);
else printf("Cycles Per Second: %luMHz", CPS/1000000);
else printf("Cycles Per Second: %luKHz", CPS/1000);
else printf("Cycles Per Second: %luHz", CPS);
printf(" (ESTIMATE) \n");
/* Get Nano Time */
const uint64_t nano = (pTime * 1000000000) / CPS;
/* Unit Simplification */
if(nano > 100000)
if(nano > 100000000)
if(nano > 100000000000)
printf("Execution Time: %lus", nano/1000000);
else printf("Execution Time: %lums", nano/1000000);
else printf("Execution Time: %luus", nano/1000);
else printf("Execution Time: %luns", nano);
printf(" (ESTIMATE)\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment