[PATCH_v2] use CLOCK_MONOTONIC_COARSE posix timer instead of CLOCK_MONOTONIC in Xorg

yakui.zhao at intel.com yakui.zhao at intel.com
Thu Aug 26 18:20:59 PDT 2010


From: Zhao Yakui <yakui.zhao at intel.com>

V1->V2:
   Limit the CLOCK_MONOTONIC_COARSE posix timer to linux platform. This is
to avoid the issue that OS doesn't support CLOCK_MONOTINC_COARSE posix timer
while the corresponding clock id is for other purpose. At the same time it
won't be created if the CLOCK_MONOTONIC_COARSE is defined in system header
file.

On some machines the HPET clock source is selected because TSC stops in course
of entering the deep C-state. And it will take about 1800 cycles to read the
HPET counter(about 1us latency). Sometimes the function of read_hpet will be
called more than 20000 every second when playing media workload. And one
important contributor is to call the CLOCK_MONOTONIC posix timer in Xorg.

     Now Linux kernel supports the CLOCK_NONOTONIC_COARSE posix timer, which
will return the time at the last tick. Compared with CLOCK_REALTIME/MONOTONIC,
it is much faster as it can avoid the access to the hardware. In such case
the application can make the trade-off between proper speed/granularity.
http://marc.info/?l=linux-kernel&m=125073483507611&w=2

     In fact the time returned by CLOCK_MONOTONIC posix timer is transferred
to millseconds. If the system tick is greater than or equal to 1000Hz, we
still can can keep the granualrity when using CLOCK_MONOTONIC_COARSE timer while
it can remove the overhead of read_hpet in Xorg.

     In our test about 12% overhead of read_hpet can be reduced when playing
the media workload, which helps to reduce the cpu C0 usage from 43% to 42%.

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Tested-by: Samuel Xu <samuel.xu at intel.com>
CC: Adam Jackson <ajax at nwnk.net>
---
 os/utils.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/os/utils.c b/os/utils.c
index 51455cc..a37a99d 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -427,7 +427,17 @@ GetTimeInMillis(void)
 
 #ifdef MONOTONIC_CLOCK
     struct timespec tp;
-    if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
+    static clockid_t clockid;
+    if (!clockid) {
+#if defined(__linux__) && defined(CLOCK_MONONOTIC_COARSE)
+	if ((clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0) &&
+		(tp.tv_nsec / 1000 <= 1000))
+	    clockid = CLOCK_MONOTONIC_COARSE;
+	else
+#endif
+	clockid = CLOCK_MONOTONIC;
+     }
+    if (clock_gettime(clockid, &tp) == 0)
         return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
 #endif
 
-- 
1.5.4.5



More information about the xorg-devel mailing list