diff --git a/src/doomtype.h b/src/doomtype.h
index 4e13ba96d3795bb9992369a48b7aacd27500ea1a..c239c7b8e91d4f7edc24ad396fb84c106eac8789 100644
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@ -379,4 +379,8 @@ Needed for some lua shenanigans.
 #define FIELDFROM( type, field, have, want ) \
 	(void *)((intptr_t)(field) - offsetof (type, have) + offsetof (type, want))
 
+#ifdef HAVE_SDL
+typedef UINT64 precise_t;
+#endif
+
 #endif //__DOOMTYPE__
diff --git a/src/i_system.h b/src/i_system.h
index dd0b65f6df542d228019f5c3c91d59c5bcd6728c..12f0d751d14eec081175d3a01fdb8a1d03647bb4 100644
--- a/src/i_system.h
+++ b/src/i_system.h
@@ -46,7 +46,13 @@ UINT32 I_GetFreeMem(UINT32 *total);
 */
 tic_t I_GetTime(void);
 
-int I_GetTimeMicros(void);// provides microsecond counter for render stats
+/**	\brief	Returns precise time value for performance measurement.
+  */
+precise_t I_GetPreciseTime(void);
+
+/**	\brief	Returns the difference between precise times as microseconds.
+  */
+int I_PreciseToMicros(precise_t);
 
 /**	\brief	The I_Sleep function
 
diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index 70ae938e935446fc2d28a7eb4682a866409fbb0c..8a70847e1e9dbe9882e46336b78cdb83d6196136 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -54,8 +54,6 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
 #include <fcntl.h>
 #endif
 
-int TimeFunction(int requested_frequency);
-
 #include <stdio.h>
 #ifdef _WIN32
 #include <conio.h>
@@ -2045,32 +2043,23 @@ ticcmd_t *I_BaseTiccmd2(void)
 // returns time in 1/TICRATE second tics
 //
 
-// millisecond precision only
-int TimeFunction(int requested_frequency)
-{
-	static Uint64 basetime = 0;
-		   Uint64 ticks = SDL_GetTicks();
-
-	if (!basetime)
-		basetime = ticks;
-
-	ticks -= basetime;
-
-	ticks = (ticks*requested_frequency);
+static Uint64 timer_frequency;
+static Uint64 tic_epoch;
 
-	ticks = (ticks/1000);
-
-	return ticks;
+tic_t I_GetTime(void)
+{
+	const Uint64 now = SDL_GetPerformanceCounter();
+	return (now - tic_epoch) * NEWTICRATE / timer_frequency;
 }
 
-tic_t I_GetTime(void)
+precise_t I_GetPreciseTime(void)
 {
-	return TimeFunction(NEWTICRATE);
+	return SDL_GetPerformanceCounter();
 }
 
-int I_GetTimeMicros(void)
+int I_PreciseToMicros(precise_t d)
 {
-	return TimeFunction(1000000);
+	return d / (timer_frequency / 1000000);
 }
 
 //
@@ -2078,6 +2067,8 @@ int I_GetTimeMicros(void)
 //
 void I_StartupTimer(void)
 {
+	timer_frequency = SDL_GetPerformanceFrequency();
+	tic_epoch       = SDL_GetPerformanceCounter();
 }
 
 void I_Sleep(void)