Last active
October 21, 2018 15:44
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*** 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